Skip to content

Instantly share code, notes, and snippets.

@dominiklohmann
Created October 7, 2022 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dominiklohmann/694afce863c8ac47739d0dba1943a89c to your computer and use it in GitHub Desktop.
Save dominiklohmann/694afce863c8ac47739d0dba1943a89c to your computer and use it in GitHub Desktop.
Response Promise Weirdness

Expected behavior: Output of 1,2,3 followed by a 5s sleep and then 4,5,6,7 Actual behavior: Output of 1,2,3,5,6,7 followed by a 5s sleep and then 4

Why does baz shut down early here?

diff --git a/libcaf_core/test/typed_response_promise.cpp b/libcaf_core/test/typed_response_promise.cpp
index 347abf9c6..ea577dadb 100644
--- a/libcaf_core/test/typed_response_promise.cpp
+++ b/libcaf_core/test/typed_response_promise.cpp
@@ -204,4 +204,66 @@ CAF_TEST(delegating_promises) {
CAF_CHECK_EQUAL(f(42), 84);
}
+CAF_TEST(broken_promise_repro) {
+ auto baz_fun = [](event_based_actor* self) -> behavior {
+ self->set_exit_handler([=](const exit_msg& msg) {
+ CAF_MESSAGE("6");
+ self->quit(msg.reason);
+ });
+ return {};
+ };
+ using bar_actor = typed_actor<replies_to<actor>::with<int>>;
+ struct bar_state {
+ typed_response_promise<int> rp = {};
+ };
+ auto bar_fun =
+ [](
+ bar_actor::stateful_pointer<bar_state> self) -> bar_actor::behavior_type {
+ self->set_down_handler([=](const down_msg&) {
+ CAF_MESSAGE("6");
+ self->state.rp.deliver(42);
+ });
+ return {
+ [=](actor baz) -> typed_response_promise<int> {
+ CAF_MESSAGE("5");
+ self->monitor(baz);
+ self->state.rp = self->make_response_promise<int>();
+ return self->state.rp;
+ },
+ };
+ };
+ using foo_actor
+ = typed_actor<replies_to<open_atom>::with<int>, reacts_to<actor>>;
+ auto foo_fun = [=](foo_actor::pointer self,
+ actor baz) -> foo_actor::behavior_type {
+ return {
+ [=](open_atom) -> typed_response_promise<int> {
+ CAF_MESSAGE("2");
+ auto request_tempporary_bar = [=](actor baz) {
+ CAF_MESSAGE("3");
+ auto bar = self->spawn(bar_fun);
+ return self->request(bar, infinite, baz);
+ };
+ self->delayed_send(self, std::chrono::seconds{5u}, baz);
+ auto rp = self->make_response_promise<int>();
+ request_temporary_bar(baz).then(
+ [rp](int x) mutable {
+ CAF_MESSAGE("7");
+ rp.deliver(x);
+ },
+ [rp](const error& err) mutable { rp.deliver(err); });
+ return rp;
+ },
+ [=](actor baz) {
+ CAF_MESSAGE("4");
+ self->send_exit(baz, exit_reason::normal);
+ },
+ };
+ };
+ CAF_MESSAGE("1");
+ auto f = make_function_view(system.spawn(foo_fun, system.spawn(baz_fun)));
+ CAF_CHECK_EQUAL(f(open_atom_v), 42);
+ CAF_MESSAGE("8");
+}
+
CAF_TEST_FIXTURE_SCOPE_END()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment