Skip to content
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

Reuse Greenlight connection #273

Closed
wants to merge 4 commits into from
Closed

Reuse Greenlight connection #273

wants to merge 4 commits into from

Conversation

roeierez
Copy link
Member

This will reuse the GL gRPC connection and reduce dramatically the number of tls handshakes.
From some tests I ran it shows 4x performance improvments.
This depends on greenlight to deploy their solution to constant URL per node.

Comment on lines 62 to 63
gl_client: Mutex::new(None),
node_client: Mutex::new(None),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if we can get away with lazy initializing the connection. That would remove the need for the Mutex, since the grpc stubs are cloneable and will manage interior mutability (muxing requests onto the single connection).

I'm not yet familiar enough with the tonic API, but I'm sure we can use the Endpoint struct with its connect_lazy method.

Copy link
Contributor

Choose a reason for hiding this comment

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

If its lazy-initialized, doesn't that mean a user action could incur an extra connection-opening time penalty?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the connection initialization will have to be anyway. Also re-connection happens from time to time automatically.

Copy link
Member Author

Choose a reason for hiding this comment

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

The schedule method connects to the scheduler and to the node gRPC endpoint.
I think if we remove the scheduler call (as we plan to) and use connect_lazy instead of connect here:
https://github.com/Blockstream/greenlight/blob/main/libs/gl-client/src/node/mod.rs#L103

Then we might be able to do it. But we also need that the new connect method will return the Client and not Result that might contain error.

Comment on lines 126 to 127
let mut node_client = self.node_client.lock().await;
if node_client.is_none() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like the recently added OnceLock in Rust 1.70 will be a good choice to init on demand here.

Copy link
Member Author

Choose a reason for hiding this comment

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

OneLock doesn't support async initialization as we need here. Also we are calling the scheduler which might return error where in that case we want to be able to try and initialize the client again. OneLock give only one shot to set the value.

Copy link
Contributor

Choose a reason for hiding this comment

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

What about some general locking pattern like

if it's not None, return it
lock a mutex
if it's not None, return it
initialize it and return it

Copy link
Member Author

Choose a reason for hiding this comment

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

Checking if not None still accesses the shared memory which requires lock. We can though use RWLock as most of the access attempts are for read.

Comment on lines 118 to 119
let scheduler =
Scheduler::new(self.signer.node_id(), self.sdk_config.network.into()).await?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the scheduler not need reuse between the gl_client and node_client?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this indeed can optimize further the startup and save one ssl handshake during startup (as currently we connect twice to the scheduler).
After submiting this: #303
It occurred to me that we can push both connections initializations to the connect (https://github.com/breez/breez-sdk/pull/303/files#diff-7466a53546c6cded460ef5502a9168b13cc930d94fdf7d0ea8166bb10c75fe7eR127) method passing both connections to the Greenlight constructor and get rid of the Mutexes totally.

@roeierez
Copy link
Member Author

roeierez commented Jul 9, 2023

@JssDWt @cdecker I am closing this in favor of #304 which seems to me a better approach.

@roeierez roeierez closed this Jul 9, 2023
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.

4 participants