hominee / crossbus

A Platform-less, Runtime-less Actor Computing Model
https://hominee.github.io/crossbus/
122 stars 0 forks source link

Actix. #3

Open uwejan opened 1 year ago

uwejan commented 1 year ago

Hello there, I am comming from actix actors background, it is working really good, especially with StreamHandlers, and webscokets, Now the project is growing and needs to put in place some sqlx queries, and that added a ton of issues, as sqlx is async, and self can not move while holding db connection. I am wondering if this crate would be an easy convert from actix, without lossing much, and gaining async await handle?

Thank you.

hominee commented 1 year ago
It is glad to see you here! and I'll summary major difference and make a simple comparison between actix and crossbus, and hope you can get a clue base on these. both of them are capable of dealing with following data types Stream waiting/blocking delay message
actix ActorStream or impl StreamHandler ActorWaitItem ActorDelayedMessageItem impl Message or ActorMessageItem
crossbus Streaming or impl Stream Blocker or impl Blocking Delayer or impl Delaying impl Message

theoretically crossbus can do what actix does in a lower level way along with more compatibility. but if you wanna use corssbus as an alternative of actix, there are some major differences you should take an eye on:

runtime actor lifecycle actor register concurrent/multi-thread
actix tokio custom creation, control by arbiter actor based, thread local Yes, depends on arbiter
corssbus runtime-less but allow any custom creation/abortion/pause/resume, control by reactor global, static Yes, depends on runtime and reactor

the way that crossbus take to tackle async/await is, to some degree, different from that actix takes. crossbus just implement Future routines and defines asynchronous event handlers, not the way actix-rt (dependency of actix) takes to directly interact with runtime.

take a more specific example, actix has a set of trait and types to asynchronously handle Message request and directly await the returned response future base on what a lot of crates create services / features / functions, like actix-web, actix-net, but crossbus don't do that way, it use the similar way as javascript callback does (in case you familiar with), you just send the message request and set the handler for the ready response, crossbus will do the rest for you.

So if you wanna an easy version of actix, the answer is obviously NO,

uwejan commented 1 year ago

Hey @hominee Thank you for taking the time to look into this, and pull up the good informations provided. I have a couple of questions;

Take for instance the following snippets from actix;

impl Handler<DbOperations> for McActor {
    type Result = String;
    //type Result = ResponseFuture<String>;
    fn handle(&mut self, msg: DbOperations, ctx: &mut Self::Context) -> Self::Result {
        return match msg {
             DbOperations::Get { key } => {
               block_on(async {
                    sqlx::query_as::<_, DbOperationValues>(select_query)
                        .bind(key)
                        .fetch_one(self.db.as_ref().unwrap())
                        .await
                        .unwrap()
                }).value

            }
            DbOperations::Set { key, value } => {   
                block_on(async {
                    sqlx::query_as::<_, DbOperationValues>(insert_query)
                        .bind(key)
                        .bind(value)
                        .fetch_one(self.db.as_ref().unwrap())
                        .await
                        .unwrap()
                }).value
            }
        };
    }
}

Since Can not use actix way handling future and returning its value with atomicResponse, i used block_on which as result, blocks the thread, causing the system to crash specially in the case of using websockets and while blocked a Pong response is not sent, not to mention other issues. Now the question, how does crossbus handle futures? Please do not tkae me wrong here and later on, I like to get clarifications before i digg deep inside the crate.

  1. Question; In the table mentioned the ablility to handle streams is available, so am assuming it wont be an issue handling websockets streas read/write within the actor?
  2. Question; In terms of platforum, it is neccersy to compile for linux/mac/windows, I notice on the crate page linux/mac only, can you clarify that for me please?
  3. Question; Does crossbus have the concept of actor to actor messaging throught threads? Say actorA on thread 1, has a referrence of actorB on thread4, and they are able to pass messages and responses.

Being said, I am thankful to your time here, I am on the phase of finding the right candidate to move on with, not necsserly will opt in but it is always good to know my options.

Thank you.

hominee commented 1 year ago

few separate points are stressed regarding to your problem:

Last but not the least, I don't recommend you to use crossbus given the situation you provide, instead, you should dig deeper over actix. As your problem is as simple as to replace block_on with Context::spawn or Addr::send, no more bother to do something else.

uwejan commented 1 year ago

Agreed. @hominee Thank you for your time. I am going to try and see what i can do. Issue can be closed. Thank you.