-
Notifications
You must be signed in to change notification settings - Fork 117
fix(l2): proof_coordinator genserver locked by tcp listen loop #4476
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
base: main
Are you sure you want to change the base?
Conversation
Lines of code reportTotal lines added: Detailed view |
MegaRedHand
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| .ok()?; | ||
|
|
||
| serde_json::from_slice(&buffer) | ||
| .map(|data| ProofCordInMessage::Request(data, Arc::new(stream))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to wrap the stream in an Arc here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically because ProofCordInMessage needs to implement Clone and TcpStream is not clonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. After the question I checked in spawned and GenServer messages need to be Clone 😅
Well, at least until lambdaclass/spawned#56 is merged 😎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And are we sure there are no good reasons for that to not be Clone? A TCP stream is not a datagram oriented socket, meaning you could race to read and write if accessing from several tasks or interleaved inside a task.
I suspect we just want the ProofCoordinator to spawn a task per connection instead. That task would do the infinite loop for as long as the connection is alive, while the ProofCoordinator is free to handle the next cast message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right! I made some changes in this commit.
Now we spawn a task that loops doing listener.accept().await. When it successfully accepts a connection it deserializes the request and then passes it and the stream over to the genserver to handle the response.
Right now I still need to wrap it in an Arc but, if the Clone requirements are removed from spawned, we can be 100% sure that only one task can have ownership of the stream at a given time so we have no races.
It might be better to spawn a new task per connection, each doing the deserializing of the request, and sending those requests to the genserver.
MegaRedHand
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks better now
Motivation
Currently the proof_coordinator Genserver can only handle a single cast message
Listen { listener: Arc<TcpListener> }as the handler for this messages starts an infinite loop that prevents other cast messages to be handled. This PR fixes that issue by moving the tcp loop into its own task.Description
spawn_listenertaskConnectionHandlergenserverCloses #3316