crux icon indicating copy to clipboard operation
crux copied to clipboard

CommandContext does not wake a pending Command stream.

Open DeltaEvo opened this issue 2 months ago • 1 comments

If a Command is returned as part of update but its CommandContext is used from another Command (for example by sending the CommandContext in an Event). Sending an Event or an Effect on the CommandContext will do nothing as the Command Stream waker by never be signaled.

(I plan to write a test exercising this to make this clearer).

This is due to the CommandContext using non async-aware channels (crossbeam ones) without manual waker handling code.

I tried updating the CommandContext to use a channel from futures, without success, as I'm missing a way to implement is_empty (used in done).

Another solution could be to share the waker from Command to CommandContext, but this would maybe break the automatic task cancellation when there is no waker left.

One last solution but seems a little hacky, would be to have another AtomicWaker just for the CommandContext :/

DeltaEvo avatar Oct 20 '25 08:10 DeltaEvo

Thanks for this! Not gonna lie, that is not a use I've ever envisioned - command context was meant to stay within its command. That said, I bet there are good uses for that.

I think this is going to be a lot easier to fix once we remove the original capabilities machinery, which I think will happen quite soon. We're currently somewhat bound to crossbeam channels.

I meant to look at https://docs.rs/flume/latest/flume/ later, they appear to support sync, async and mix and match.

charypar avatar Oct 21 '25 09:10 charypar

@DeltaEvo I've merged #443 removing the capability runtime entirely, which should mean the channel implementation is now contained inside the Command implementation, which should let us experiment with different channel types.

It will get released on 0.17, but if you wanna experiment a bit on master, it should have much less far reaching consequences now, I hope.

charypar avatar Nov 16 '25 15:11 charypar

Sorry, forgot to update our progress here, after your answer we tried implementing it with flume but it wasn't very straightforward as flume asks you to keep the stream around meaning that in the command we needed to keep both a receiver and a stream :(.

I'll take a look at #433, if it works like I think, you might have solved the bug as the executor will not use the stream anymore.

DeltaEvo avatar Nov 18 '25 16:11 DeltaEvo

Since #443 , there is no more executor, there's a root command instead (which has an executor inside of it)

charypar avatar Nov 18 '25 17:11 charypar