Fix: Properly handle surface close event and operations.#444
Fix: Properly handle surface close event and operations.#444Ph4ntomas wants to merge 10 commits into
Conversation
1cb61bd to
10e063d
Compare
|
Okay this works as far as I can tell, but I need to check/implement the lua side |
|
I now wonder if I should push this server-side, so it doesn't requires client-side tricks |
10e063d to
a970aef
Compare
Okay, so I did explore that route a bit, but came upon the following issue:
On the other hand, fixing ordering in lua the same way it was done in rust only required yield-able stream/channels. Those can be built from cqueues's promise and/or conditional variables, as cqueues is coroutine-based (no two coroutine runs at the same time) I went with a simple "spsc"-ish channel. |
|
Some notes: The way I see it, two improvements could be done:
I'm not doing that here, as I don't really see any need for it at the moment. |
a970aef to
df060c1
Compare
problem: When a big payload is sent while another one is polling, cqueues.poll sometime does a spurious wakeup and returns nil. This makes stream:each_chunk() exit early, which in term closes streams. When a stream exits in this state, the server may still send some event, causing the config to crash. solution: We workaround this bug by implementing our own each_chunk function which will ignore timeout (in this context, a timeout should never happen, so it's as safe as can be). We don't need to implement that for regular call to stream:get_next_chunk as they are all done with a timeout, which would already loop correctly.
problem: it's possible for operate() call to apply on a stale view if a view is pending, leading to some operation failing. solution: There are two part of this fix: 1. Enforce ordering of update and operate message by using the message queue used by message 2. Delay sending operate calls to the server until after the view was sent.
On the rust-side, we had to ensure operations went through the message channel so they can't be sent to the server while an update is in progress. This avoid cases where we're sending a focus event as part of an update, but the widget we're trying to focus has not yet been seen. This commit implements the same logic on lua, which needed refactoring the code to have the same kind of "mainloop" we have in rust. The event stream is implemented using the newly added `snowcap.util.channel` which uses cqueues promise to have an async channel/stream.
On the rust-side, we had to ensure operations went through the message channel so they can't be sent to the server while an update is in progress. This avoid cases where we're sending a focus event as part of an update, but the widget we're trying to focus has not yet been seen. This commit implements the same logic on lua, which needed refactoring the code to have the same kind of "mainloop" we have in rust. The event stream is implemented using the newly added `snowcap.util.channel` which uses cqueues promise to have an async channel/stream.
On the rust-side, we had to ensure operations went through the message channel so they can't be sent to the server while an update is in progress. This avoid cases where we're sending a focus event as part of an update, but the widget we're trying to focus has not yet been seen. This commit implements the same logic on lua, which needed refactoring the code to have the same kind of "mainloop" we have in rust. The event stream is implemented using the newly added `snowcap.util.channel` which uses cqueues promise to have an async channel/stream.
df060c1 to
cb2b83f
Compare
This PR handle several things:
FIX done:
I've merged changes from #445 into this PR as it made reworking lua easier.
Fixes: #443
Supersedes: #445
Original description
problem: it's possible for operate() call to apply on a stale view if a view is pending, leading to some operation failing.
solution: There are two part of this fix:
Fixes: #443