Skip to content

Refactoring to better support new protocol versions #400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 23, 2018

Conversation

lutovich
Copy link
Contributor

@lutovich lutovich commented Aug 22, 2018

  • Extract protocol negotiation into a dedicated class. It encapsulates all the logic related to the Bolt protocol negotiation and versioned packstream components
  • Connection is now less coupled with protocol messages. It is able to write an arbitrary RequestMessage instead of exposing functions to write messages of a specific type, like Connection#pullAll(). Also introduced a BoltProtocol abstraction which exposes only logical operations, like "initialize the connection" or "run a query". It should make it simpler to introduce new protocol version that uses different messages to execute same logical operations.
  • Expose transaction operations on BoltProtocol. Make it expose logical operations for explicit transactions like begin, commit and rollback. These operations require different set of messages in Bolt V3. Having operations exposed like this should make it easier to override them.

It encapsulates all the logic related to the Bolt protocol
negotiation and versioned packstream components.
Connection is now less coupled with protocol messages. It is able
to write an arbitrary `RequestMessage` instead of exposing functions
to write messages of a specific type, like `Connection#pullAll()`.
Also introduced a `BoltProtocol` abstraction which exposes only logical
operations, like "initialize the connection" or "run a query". It
should make it simpler to introduce new protocol version that uses
different messages to execute same logical operations.
@lutovich lutovich requested a review from ali-ince August 22, 2018 12:44
Make it expose logical operations for explicit transactions like begin,
commit and rollback. These operations require different set of messages
in Bolt V3. Having operations exposed like this should make it easier
to override them.
Moved creation of `Packer` and `Unpacker` into `BoltProtocol` because
they are in lockstep with each other. This makes protocol handshaker
simpler because it only needs to do a single version check. Introduced
a class that represents Bolt V2 with different packing and unpacking
capabilities.
Add a configuration option to the neo4j.conf file to speed-up some
tests. New value is 5 seconds instead of default 30 seconds.
Routing driver removes address from the routing table on error. This
removal is triggered by a `StreamObserver` that observes the incoming
messages. Same observer is used for RUN and PULL_ALL. It used to
trigger the forget operation trice on every error. This wasn't harmful
but looked weird in logs.

This commit fixes the problem by making `StreamObserver` invoke the
provided callback only once.
Copy link
Contributor

@ali-ince ali-ince left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, only had a couple of comments about naming.

* @return {BoltProtocol} bolt protocol corresponding to the version suggested by the database.
* @throws {Neo4jError} when bolt protocol can't be instantiated.
*/
readHandshakeResponse(buffer) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to name this to something like createNegotiatedProtocol? Wdyt?

* @throws {Neo4jError} when bolt protocol can't be instantiated.
*/
readHandshakeResponse(buffer) {
const proposedVersion = buffer.readInt32();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this maybe to negotiatedVersion?


// for commit & rollback we need result that uses real connection holder and notifies it when
// connection is not needed and can be safely released to the pool
return new Result(observer, msg, {}, emptyMetadataSupplier, connectionHolder);
return new Result(observer, '', {}, emptyMetadataSupplier, connectionHolder);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to use something other than '' here - just for clarity?

 * Use new query parameter syntax `$param` instead of deprecated `{param}`
 * Do not use ES6 dynamic object key syntax
 * improve naming of functions and variables in `ProtocolHandshaker`
 * preserve statement for commit and rollback results for backwards
   compatibility
@lutovich lutovich merged commit b2e62e6 into neo4j:1.7 Aug 23, 2018
@lutovich lutovich deleted the 1.7-bolt-protocol branch August 23, 2018 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants