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

inline_all_enqueues not working as expected #1016

Closed
xiewei20082008 opened this issue Jan 17, 2020 · 3 comments · Fixed by #1017
Closed

inline_all_enqueues not working as expected #1016

xiewei20082008 opened this issue Jan 17, 2020 · 3 comments · Fixed by #1017
Labels
Milestone

Comments

@xiewei20082008
Copy link

xiewei20082008 commented Jan 17, 2020

Unit tests fail to work on the code where scoped_actor is involved. I tried to add sched.inline_all_enqueues() before, but it still didn't work. Is there any way to make the scheduler run? The sample code is as follows. Thank you a lot.

behavior inc_impl(event_based_actor *self) {
  return {
    [=](int x) {
      return x+1;
    }
  };
}

behavior a_impl(event_based_actor *self, actor &inc_actor) {
  return {
    [=](int x) {
      if (x==1) {
        scoped_actor sc{self->system()};
        cout << "before request" << endl;                            
        sc->request(inc_actor, caf::infinite, 1).receive(    // get stuck here.
          [=](int x) {
            cout << x << endl;
          },
          [=](caf::error &e) {}
        );
        cout << "after request" << endl;
      }
      else if(x==2) {
        cout << "before request" << endl;
        make_function_view(inc_actor)(1);    // get stuck here.
        cout << "after request" << endl;
      }
    }
  };
}

struct test_fixture : test_coordinator_fixture<> {
    test_fixture() {
    }
};

CAF_TEST_FIXTURE_SCOPE(test1, test_fixture)

CAF_TEST(blocked actor) {
  sched.inline_all_enqueues();
  auto inc_actor = sys.spawn(inc_impl);
  auto a_actor = sys.spawn(a_impl, inc_actor);
  self->send(a_actor, 1);
  // self->send(a_actor, 2);
  run();
}

CAF_TEST_FIXTURE_SCOPE_END()
@Neverlord
Copy link
Member

Thanks for providing the minimal example. I've reproduced the issue and I've implemented a patch. If the PR gets merged, I'll also provide the patch in the branch topic/0.17.4 (using the master branch is currently not a good idea, since it contains some breaking changes and more are coming for the upcoming 0.18 release).

However, please note that using a scoped actor inside an event-based actor is not safe. Event-based actors are scheduled cooperatively, this means they are supposed to "play nice" with each other.

The scheduler waits for the actor to return from its message handler before it can run other actors. Blocking a scheduler thread can degrade performance and cause starvation or even deadlocks.

Please consider using self->request().then/await instead or switch to using blocking actors instead if you really need a blocking receive.

@Neverlord Neverlord changed the title test_coordinator_fixture's scheduler suspended in blocking actor. inline_all_enqueues not working as expected Jan 18, 2020
@xiewei20082008
Copy link
Author

Also thank you for the advise on using event-based actors. I refactored my code - it was of great help to me.

@Neverlord
Copy link
Member

My pleasure. :)

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

Successfully merging a pull request may close this issue.

2 participants