tqwewe / kameo

Fault-tolerant Async Actors Built on Tokio
https://docs.page/tqwewe/kameo
Apache License 2.0
630 stars 15 forks source link

Attach `Streams` to actors #15

Closed flxo closed 7 months ago

flxo commented 7 months ago

To process a Stream in a Kameo actor I think currently the only solution is to spawn a (Tokio) task and forward each item to the actor. Each item must be sent through the actors queue. Spawning the task and moving a ActorRef inside etc... is boilerplate and boring.

I remember that at least actix has a feature to attach streams to actors and wondered if that could be considered a feature for kameo as well?

If yes:

I hacked a prototype and noticed that every message in kameo get's boxed and was very surprised because this is generally considered as a possible performance hit. Is there no way around that? Sadly I had to do the same for the stream feature.

In the prototype an actor is not notified if a stream completes. This could be easily achieved by using StreamNotifyClose. This would be a API decision. I think it's a nice feature but adds noise and possible confusion because the handler need to have an Option around each message. This implicity must be know and may be hard to get for beginners.

Thanks for your thoughts!

flxo commented 7 months ago

Small addition: I think you definitely want the "notify the actor on stream finished" feature.

tqwewe commented 7 months ago

I remember that at least actix has a feature to attach streams to actors and wondered if that could be considered a feature for kameo as well?

Yes definitely seems useful!

I hacked a prototype and noticed that every message in kameo get's boxed and was very surprised because this is generally considered as a possible performance hit. Is there no way around that? Sadly I had to do the same for the stream feature.

Yeah I'm not sure if there's any way to create actors like this without boxing messages, unless the messages are all defined in one giant enum, which can become ugly pretty quickly imo. So kameo boxes messages and downcasts them, however all the downcasting is done internally so it's all safe. But there would be a performance hit when comparing to using a raw enum.

This could be easily achieved by using StreamNotifyClose. This would be a API decision. I think it's a nice feature but adds noise and possible confusion because the handler need to have an Option around each message.

Wrapping the items in an Option definitely would work! I'll try to figure out a nice API for this and ping you in a PR if I figure it out. I've checked out your fork and seems like your version would work pretty well! Though I'm hoping it could be done without adding another branch to the tokio::select in the actor spawn logic

tqwewe commented 7 months ago

I've just made a PR, if you get a chance I'd love to see if this works for you. It does exactly what you described, spawns a tokio task and forwards messages to the actor. But in order to differentiate from regular messages, and the ability to act when the stream finishes, I added the StreamMessage trait with the finished method.

This way nothing needs to be added to the core logic of the actor mailbox loop code