Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ideas on further API change #55

Open
Horusiath opened this issue May 3, 2017 · 7 comments
Open

Ideas on further API change #55

Horusiath opened this issue May 3, 2017 · 7 comments

Comments

@Horusiath
Copy link
Owner

Horusiath commented May 3, 2017

There are several ideas I have on potential changes concerning current API, some of them are breaking changes:

  1. Move away from returning effects. I still need to evaluate on that, but I think, it might be better to leave effect-free code in user hands. Requiring to return effect is pretty ugly in longer run, and it looks bad in terms of composition with user-defined code. Simple unit return may be enough.
  2. Move away from AskResult<>: by default we should be able to interop with ask pattern just by using let! response = ref <? request and not having to unwrap the code each time if not necessary. If someone wants to have it presented in form of an object, he could use try pattern line let 'try block = try Success <| block() with e -> Failure e.
  3. Since we expose actor context directly as function parameter, we might want to simply provide a mock for it in TestKit, that will record all method calls in form of list of events that we could use for assertions later. This way we could make unit tests on actors without need of creating a whole actor system, just passing context mock.
  4. Look forward If we are able to fully integrate with async { ... } computation expression. The idea here is to be able to define actor not only from actor { ... } but directly from async look as well.

In general I'd like to reduce a footprint of Akkling API in user code in a way that user could potentially define his/her domain logic with minimal dependencies to Akka.NET/Akkling libraries.

@Neftedollar
Copy link

I like 2nd, 3d and 4th points. I like your general idea.
But what about effects? I understand that they are not following the idea of reducing API, but they are still very useful. Maybe they can be an optional extension library? (sorry if I've made mistakes in the text)

@daniellittledev
Copy link
Contributor

  1. Would this move to using side effects instead?
  2. Awesome, this has always bugged me, I think I commented it on it before
  3. I've started doing something similar already, I can call stepNext on an an effect and collect a stream of tell events.
  4. This sounds cool, I've also wanted to be able to compose actor. Possibly call Recieve in a nested fashion. It sort of worked, one of the things I played with was creating my of ResultEffect type to get the value out but it was pretty clunky.

@Horusiath
Copy link
Owner Author

Horusiath commented May 4, 2017

@lavinski :

  1. With current design we already have side effects. Things like setting up receive timeout, even sending a message to another actor, are actually side effects. While it is possible to build side-effect free code by the user, making a whole API to work that way seems to be counter-productive. But as I said this decision still needs to be evaluated.
  2. AFAIK you can call Receive multiple times to get multiple messages. async can also be composed inside actor expression (starting from v0.5 if I remember correctly). What I want to do is to make props creator to work with both actor/async expressions.

@Neftedollar
Copy link

@Horusiath
How do you think, when will your API changes be started/released?
I want to use Akkling at my work, but I've got some doubts about the status of it. Is it production ready now? If I start using it now, how much time should I consider for the subsequent migration to the new API?

@daniellittledev
Copy link
Contributor

daniellittledev commented May 13, 2017

@Horusiath

With regards to composing actor I'm taking about calling Receive once in a nested fashion.

let receivePreProcess mailbox = actor {
    let! msg = mailbox.Receive()
    
    match msg with
    | :? X -> Ignore
    | _ -> ReturnValue msg
}

let rec loop () = actor {

    let! message = receivePreProcess mailbox

    loop ()
}

@Horusiath
Copy link
Owner Author

@Neftedollar most of the API will remain intact, while things like Effects and AskResult will probably be simplified, this won't be as noisy change as one would except in user code. I.e. while I want to get rid of Effect<>, user intent will still be possible to declare directly via returned behavior (see how akka-typed introduced behaviors).

Sample code:

let ref = spawn system "my-actor" <| props(fun ctx ->
    let rec loop () = actor {
        let! msg = m.Receive ()
        match msg with
        | "stop" -> return Stop
        | "unhandle" -> return Unhandled
        | x ->
            printfn "%s" x
            return! loop ()
    }
    loop ())

This looks exactly like existing code however, Stop and Unhandled won't be instances of Effect<> interface any more, they will be behaviors (just like the loop function itself).

@rabejens
Copy link

rabejens commented Nov 18, 2021

I would like a ReceiveAny function on the context. Background: Often, an actor has child actors that do some elaborate work, and I can't always use <?, because I have scenarios where I , e.G., send an 'A to the child and get multiple 'B back. However, I don't want to make all my actors Actor<obj>.

I want to have something like this:

let floater (ctx: Actor<int>) =
    let rec loop() = actor {
        let! i = ctx.Receive()
        ctx.Sender() <! (float i)
        return! loop()
    }
    loop()
let inter (ctx: Actor<int>) =
    let f = spawnAnonymous ctx (props floater)
    let rec loop() = actor {
        match! ctx.ReceiveAny() with // should return obj
        | :? int as i -> f <! i
        | :? float as flt -> printfn "Received a float: %f" flt
        return! loop()
    }
    loop()

So, the actor still only accepts int from the outside but can accept anything from the inside.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants