-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Hello,
First I'd like to thank you for your work on Boltex, it's a great tool, and along Bolt sips, to be able to use Neo4j with elixir is really enjoyable.
Recently, someone adds an issue on your project regarding temporal types which are implemented in Neo4j 3.4 and there isn't answers from you yet.
As an exercise, and because I need Neo4j for a future project, I wanted to make Boltex evolve and implement temporal / spatial types, which are in fact the V2 of the Neo4j bolt protocol.
Because I'm new to binary manipulation, and not so much experienced with elixir, I didn't really understand your code and things work. Then I decided to read about bolt protocol, read Neo4j's driver code for Js and python and your code, and code my own driver.
I ended up with something working, you can see it here: https://github.com/dominique-vassard/bolt-neo4j.
Now that I have a fully working driver and that I understand how things work, I'd like to collaborate to boltex and make it evolve.
But before, I have to understand some of choice and discuss some of choices I've made.
Messages as first decode stage
As you can see here: https://github.com/dominique-vassard/bolt-neo4j/blob/master/lib/bolt_neo4j/packstream/message.ex
I've implemented messages as struct.
This what done in order to have encoding / decoding completely decoupled from communication.
Then if you look in bolt.ex, there's nothing regarding signature, marker except for the handshake (which should be treated as the other message though) and some <<0x00, 0x00>>
I think it is a good idea to have things structured like: Communication -> Message encoding / decoding -> Data encoding / decoding.
It will be easier to work on specific.
What do you think?
Bolt structure
I saw that none of the specific structures (node, relationship, path) are implemented in boltex. they are implemented in bolt_sips. Is there a specific reason for this?
Because bolt_sips knows about some specific signatures which are bolt-related. Won't bolt_sips should be only aware about client-server communication and use only this part of boltex?
Logs
There's no logs at all in your driver, and I found it hard to follow the data flow when I need it. In my project, I log every message between server and client, and that was easier to spot my errors and understand the communication flow.
Logs are similar to those implemented in Neo4j's Python and JS driver and looks like follow:
11:37:31.650 [debug] C: HANDSHAKE ~ "<<0x60, 0x60, 0xB0, 0x17>> [2, 1, 0, 0]"
11:37:31.652 [debug] S: HANDSHAKE ~ <<0, 0, 0, 1>>
11:37:31.652 [debug] C: INIT ~ %BoltNeo4j.Packstream.Message.Init{auth_token: %{credentials: "test", principal: "neo4j", scheme: "basic"}, client_name: "BoltNeo4j/0.1"}
11:37:31.654 [debug] S: RAW_DATA ~ <<0xB1, 0x70, 0xA1, 0x86, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x8B, 0x4E, 0x65, 0x6F, 0x34, 0x6A, 0x2F, 0x33, 0x2E, 0x33, 0x2E, 0x36>>
11:37:31.655 [debug] S: SUCCESS ~ %{"server" => "Neo4j/3.3.6"}
11:37:31.655 [debug] C: RUN ~ %BoltNeo4j.Packstream.Message.Run{parameters: %{}, statement: "RETURN 1 AS num"}
11:37:31.655 [debug] C: RUN ~ <<0x0, 0x13, 0xB2, 0x10, 0x8F, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4E, 0x20, 0x31, 0x20, 0x41, 0x53, 0x20, 0x6E, 0x75, 0x6D, 0xA0, 0x0, 0x0>>
11:37:31.658 [debug] S: RAW_DATA ~ <<0xB1, 0x70, 0xA2, 0xD0, 0x16, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x5F, 0x61, 0x76, 0x61, 0x69, 0x6C, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2, 0x86, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x73, 0x91, 0x83, 0x6E, 0x75, 0x6D>>
11:37:31.658 [debug] S: SUCCESS ~ %{"fields" => ["num"], "result_available_after" => 2}
11:37:31.658 [debug] C: PULL_ALL ~ []
11:37:31.660 [debug] S: RAW_DATA ~ <<0xB1, 0x71, 0x91, 0x1>>
11:37:31.660 [debug] S: RECORD ~ [1]
11:37:31.660 [debug] S: RAW_DATA ~ <<0xB1, 0x70, 0xA2, 0xD0, 0x15, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x73, 0x75, 0x6D, 0x65, 0x64, 0x5F, 0x61, 0x66, 0x74, 0x65, 0x72, 0x0, 0x84, 0x74, 0x79, 0x70, 0x65, 0x81, 0x72>>
11:37:31.660 [debug] S: SUCCESS ~ %{"result_consumed_after" => 0, "type" => "r"}
I think it would be great to have those in Boltex too. What do you think?
Of course, there are only for debug purpose and something should be done for the auth struct, which should'nt appear in logs.
Bolt v2
I think this part should be discussed with @florinpatrascu too.
As you may know, temporal and spatial types are supported in this new Bolt version.
It seems that Bolt V2 specs are not completely frozen and that some parts could be updated.
But in all case, it may be interesting to provide the V2 feature to Neo4j & elixir users.
With assumptions discussed above (struct in bolt_neo4j, logs, etc.), I've implement it and it works fine.
We have 2 options here:
- don't implement struct in boltex: then it's just a matter of asking for [2, 1, 0, 0] during hanshake to favour Bolt V2 when it's available and everything will work and new temporal / spatial types shoudl be implemented in bolt sips.
- implement struct in boltex: then there is more work for the boltex team (check the protocol version, decoding to new types) and almost none for bolt_sips, but then it will be wise to implement node, relationship and path struct in boltex too, in order to be coherent.
You can take a look at the decoder_v2.ex to see what's going here: first proposal and its retruns are in comments, and the implementation is with new types.
Again, I want this to be clear, even if I have a fully working Boltex ersatz, my goal is not to replace it but to collaborate with you on it and help you maintaining it. An I hope it will be the case.
Thank you,
Dominique