insanitybit / aktors

Rust actor library with a bit of inspiration from Akka/Pykka
MIT License
45 stars 3 forks source link

Type safe actors #2

Open insanitybit opened 7 years ago

insanitybit commented 7 years ago

There are two significant problems with Aktors as it stands:

1) My assumption is that performance is considerably hurt by dynamic dispatch used rampantly

2) You can send a message to an actor that it can not handle, and this is a runtime failure

Both of these are solved with a type safe actor system, one where you can determine at compile time what messages an actor can handle.

I think that borrowing from Pony is the way to go, as they have an incredibly ergonomic, typesafe actor system.

Having played around with the idea I think what I want is something along these lines:

Take this non-actor code:

struct Foo {
    state: u64
}

impl Foo {
    fn do_a_thing(thing: u64) {
        // do stuff
    }
}

and generate something like this:

enum FooActorMessage {
    DoAThing{ thing: u64 }
}

struct FooActor {
    mailbox: Queue
}

impl FooActor {
    fn do_a_thing(thing: u64) {
        let msg = FooActorMessage{ thing: thing };
        mailbox.send(msg);
    }
}

This would maintain type safety and really cleanly define the concept of behaviors as separate functions.

The problem is, how does one respond? There must be a Sender where A is another actor reference type.

This is where Actor Traits will come in. Given a Trait implemented by an Actor a message type M will be generated for that trait. Therefor you can respond to any actor given that it implements A.

trait SomeTrait {
    // u64 for processing, Sender to the Trait SomeTrait for returning values
    fn do_trait_thing(u64, SomeTrait);
}

enum SomeTraitActorMessage {
    DoTraitThing{ u64, SomeTrait }
}

struct FooActor {
    mailbox: Queue
}

impl FooActor {
    fn do_a_thing(thing: u64, sender: SomeTrait) {
        let msg = DoTraitThing{ thing, sender };
        mailbox.send(msg);
    }
}

That's a rough sketch of the concept. All of this will have to be generated via macros, but it should provide a nice generic type safe actor system.

insanitybit commented 7 years ago

This will also mean generating a 'dispatch' or 'on_message' function in the Foo impl that takes messages off of the queue and calls the appropriate function.

insanitybit commented 7 years ago

https://www.reddit.com/r/rust/comments/66kar2/anyone_familiar_with_macros_in_rust_looking_for/

insanitybit commented 7 years ago

https://github.com/insanitybit/derive_aktor

Going to mess around with the concept in that repo.