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

Reply after emit without state doesn't compile #105

Closed
johanandren opened this issue Nov 6, 2023 · 9 comments
Closed

Reply after emit without state doesn't compile #105

johanandren opened this issue Nov 6, 2023 · 9 comments

Comments

@johanandren
Copy link
Member

From the docs I had expected this to be possible:

emit_event(Event::SomeEvent { stuff }).reply(reply_to, some_reply)

But I get an error for the reply call saying "method not found in `EmitEvent<_>"

@patriknw
Copy link
Member

patriknw commented Nov 6, 2023

Did you try #99 ?

@johanandren
Copy link
Member Author

Yes, that's what I'm using now as a workaround (and_then_reply) but I don't need the state for the reply and sending the reply doesn't result in a future, so it looks somewhat clumsy:

emit_event(Event::DeliverySelected {
    delivery: DeliveryInProgress {
        drone_id,
        delivery_id: delivery.delivery_id.clone(),
        pickup_time: Utc::now()
    }
}).and_then_reply(move |_queue: &Self,
                        _new_state: Option<&State>,
                        _prev_result: effect::Result| {
    reply_to.send(Some(delivery));
    // fixme don't pretend we wait for something async?
    future::ready(Ok(()))
}).boxed()

When what I'd expected from the API docs is:

emit_event(Event::DeliverySelected {
    delivery: DeliveryInProgress {
        drone_id,
        delivery_id: delivery.delivery_id.clone(),
        pickup_time: Utc::now()
    }
}).reply(reply_to, delivery)

@johanandren
Copy link
Member Author

I figured out how to do it (so maybe more motivation for #104 ):

emit_event(Event::DeliverySelected {
      delivery: DeliveryInProgress {
          drone_id,
          delivery_id: delivery.delivery_id.clone(),
          pickup_time: Utc::now()
      }
  }).and(reply(reply_to, Some(delivery))).boxed()

@huntc
Copy link
Collaborator

huntc commented Nov 6, 2023

I wasn't sure whether I should supply conveniences for the successful completion case as well was the more comprehensive and_then_ ones that permit a result to be tested.

I could compliment all of the and_then_ combinators with then_ ones which execute only on success if you'd think this'd be useful.

@johanandren
Copy link
Member Author

Closed but didn't see your comment, so reopening.

Specifically persist and then ack is probably one of the two most common path for a command handler, so it might make sense with a .then_reply convenience, the other most common path would be persist and then reply with something from the resulting state which should already be covered by the and_then_reply (although I'm not entirely sure about the future return there, isn't the reply a fire-and-forget?) .

@johanandren johanandren reopened this Nov 6, 2023
@patriknw
Copy link
Member

patriknw commented Nov 6, 2023

Having both then_reply and and_then_reply seems confusing to me, or is that such a well established convention in Rust that everyone know that difference in semantics?

If I understand it correctly it's not possible to have overloaded functions? Same name different parameters.

@johanandren
Copy link
Member Author

Looking at the TryFutureExt what I understand is that and_then is the mapAsync of Rust land (so only about dealing with success of the previous step).

The then_reply I suggested is just me mapping the JVM API 1:1 (thenReply(replyTo)(state => reply)), there we don't really have any overloads, since it is pretty clean to ignore the state with _ but here the and_then_reply takes three parameters, self, result of previous effect and the state, to ignore and wants a future result.

In the JVM we never talk about the failure case, so maybe dropping that from the effect DSL would clean things up a bit, only have composition for the happy path and fail the entity for errors. Not sure if I saw any previous discussion/decision on that aspect.

We also do not have any async-chains there, and separate the main effect from side effects, which keeps things a bit simpler.

@huntc huntc mentioned this issue Nov 9, 2023
@huntc
Copy link
Collaborator

huntc commented Nov 9, 2023

OK, given #114 it'd be great if we could review and possibly close this. Thanks.

@johanandren
Copy link
Member Author

I didn't try it yet, but since the test does the exact thing we can close.

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

No branches or pull requests

3 participants