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

fix: empty stream state on broadcast #129

Merged
merged 4 commits into from
Feb 19, 2024

Conversation

EnriqueL8
Copy link
Contributor

@EnriqueL8 EnriqueL8 commented Feb 19, 2024

When a broadcast is attempted and the steam state hasn't been initialise it caused a nil pointer.

Two ways to solve this:

  • If the stream state is nil, set an empty one as part of broadcast but that means no connections will receive those messages until that map updates
  • Wait for a least one connection on this stream to start and then start broadcasting. At least one connection will receive the messages for the stream whilst it's connected

I've gone for the latter one. We perform best-effort delivery for broadcast, so it could be argued to do the former, any thoughts appreciated!

Signed-off-by: Enrique Lacal <enrique.lacal@kaleido.io>
@codecov-commenter
Copy link

codecov-commenter commented Feb 19, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (ea9c63d) 100.00% compared to head (5a8e0ab) 100.00%.

❗ Current head 5a8e0ab differs from pull request most recent head 891eea2. Consider uploading reports for the commit 891eea2 to get more accurate results

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #129   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           79        79           
  Lines         6473      6476    +3     
=========================================
+ Hits          6473      6476    +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Signed-off-by: Enrique Lacal <enrique.lacal@kaleido.io>
Copy link
Contributor

@nguyer nguyer left a comment

Choose a reason for hiding this comment

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

I'm not sure that this solution is consistent with the way we have viewed these types of connections throughout our architecture. The "Broadcast" function is expected to be non-blocking and any code should be able to call it regardless of whether any clients are current connected. The Broadcast function specifically is also not intended to be a durable message queue (as opposed to the RoundTrip function), which I think these changes have begun to alter. It is expected that if something is broadcasted (a TX receipt for example) while my client is not connected, if I am interested in that receipt, when I need to query for it when my client connects. I expect to be caught up on batches that I have missed (the durable part of the stream), but broadcasts are a different thing altogether.

// Waiting for a least one connection to start the stream
// before we start broadcasting
// Err always nil per callback function
_ = s.waitStreamConnections(ctx, stream, func(providedState *streamState) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does waitStreamConnections block here if nobody is connected?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it does block

@EnriqueL8
Copy link
Contributor Author

EnriqueL8 commented Feb 19, 2024

Exactly what I thought that is why I left it for the reviewer to decide on which option is best - just ignore that message if no connection are available or wait until a connection is available. You are leaning towards the former but does that mean that "starting" a stream means start listening from now , not from the beginning of the events this stream cares about. If we are fine with that, I am happy to make my original change of just setting the state of stream without any connections on the first broadcast for the stream

This will not be true I expect to be caught up on batches that I have missed and continue to be true if you are late joiner to a broadcast stream. Only will occur if you reset the stream.

@nguyer
Copy link
Contributor

nguyer commented Feb 19, 2024

Broadcasts are not durable, so if I (as a websocket client) start listening, I only expect to get broadcasts that happen while I'm connected

Signed-off-by: Enrique Lacal <enrique.lacal@kaleido.io>
@nguyer
Copy link
Contributor

nguyer commented Feb 19, 2024

This will not be true I expect to be caught up on batches that I have missed and continue to be true if you are late joiner to a broadcast stream

That's fine. Broadcasts and batches that go through the RoundTrip are different in this regard.

Signed-off-by: Enrique Lacal <enrique.lacal@kaleido.io>
@EnriqueL8
Copy link
Contributor Author

EnriqueL8 commented Feb 19, 2024

Just to clarify we are broadcasting batches as well so batching and delivery methods are completely different and configured independently.

Have pushed the simpler change to just populate the stream state

@nguyer nguyer merged commit b875778 into hyperledger:main Feb 19, 2024
2 checks passed
@nguyer nguyer deleted the fix_broadcast_nilpointer branch February 19, 2024 16:27
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.

3 participants