Unverified Commit ea9fb5d4 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #1376

Add missing member functions to typed_actor_view
parents 3ae23f9e a8a3df79
......@@ -14,6 +14,8 @@ is based on [Keep a Changelog](https://keepachangelog.com).
- Add new `*_weak` variants of `scheduled_actor::run_{delayed, scheduled}`.
These functions add no reference count to their actor, allowing it to become
unreachable if other actors no longer reference it.
- Typed actors that use a `typed_actor_pointer` can now access the
`run_{delayed,scheduled}` member functions.
### Fixed
......
......@@ -10,6 +10,8 @@
namespace caf {
/// Provides a view to an actor that implements this messaging interface without
/// knowledge of the actual type.
template <class... Sigs>
class typed_actor_pointer : public typed_actor_view_base {
public:
......@@ -76,8 +78,12 @@ public:
return &view_;
}
explicit operator bool() const {
return static_cast<bool>(view_.internal_ptr());
bool operator!() const noexcept {
return internal_ptr() == nullptr;
}
explicit operator bool() const noexcept {
return internal_ptr() != nullptr;
}
/// @private
......
......@@ -204,6 +204,35 @@ public:
self_->send_exit(whom, std::move(reason));
}
// -- scheduling actions -----------------------------------------------------
/// @copydoc scheduled_actor::run_scheduled
template <class Clock, class Duration, class F>
disposable
run_scheduled(std::chrono::time_point<Clock, Duration> when, F what) {
return self_->run_scheduled(when, std::move(what));
}
/// @copydoc scheduled_actor::run_scheduled_weak
template <class Clock, class Duration, class F>
disposable
run_scheduled_weak(std::chrono::time_point<Clock, Duration> when, F what) {
return self_->run_scheduled_weak(when, std::move(what));
}
/// @copydoc scheduled_actor::run_delayed
template <class Rep, class Period, class F>
disposable run_delayed(std::chrono::duration<Rep, Period> delay, F what) {
return self_->run_delayed(delay, std::move(what));
}
/// @copydoc scheduled_actor::run_delayed_weak
template <class Rep, class Period, class F>
disposable
run_delayed_weak(std::chrono::duration<Rep, Period> delay, F what) {
return self_->run_delayed_weak(delay, std::move(what));
}
// -- miscellaneous actor operations -----------------------------------------
void quit(exit_reason reason = exit_reason::normal) {
......
......@@ -13,14 +13,43 @@ using namespace std::literals;
namespace {
using fixture = test_coordinator_fixture<>;
behavior dummy_behavior() {
behavior int_behavior() {
return {
[](int) {},
};
}
using int_actor = typed_actor<result<void>(int)>;
using int_actor_ptr = int_actor::pointer_view;
struct int_actor_state {
using init_fn = std::function<void(int_actor_ptr)>;
int_actor_state(int_actor_ptr ptr, init_fn fn)
: self(ptr), init(std::move(fn)) {
// nop
}
int_actor::behavior_type make_behavior() {
init(self);
return {
[](int) {},
};
}
int_actor_ptr self;
init_fn init;
};
using int_actor_impl = int_actor::stateful_impl<int_actor_state>;
struct fixture : test_coordinator_fixture<> {
int_actor spawn_int_actor(int_actor_state::init_fn init) {
return sys.spawn<int_actor_impl>(std::move(init));
}
};
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
......@@ -32,7 +61,7 @@ SCENARIO("run_delayed triggers an action after a relative timeout") {
auto called = std::make_shared<bool>(false);
auto aut = sys.spawn([called](event_based_actor* self) {
self->run_delayed(1s, [called] { *called = true; });
return dummy_behavior();
return int_behavior();
});
sched.run();
CHECK(!*called);
......@@ -45,7 +74,35 @@ SCENARIO("run_delayed triggers an action after a relative timeout") {
auto pending = disposable{};
auto aut = sys.spawn([called, &pending](event_based_actor* self) {
pending = self->run_delayed(1s, [called] { *called = true; });
return dummy_behavior();
return int_behavior();
});
sched.run();
CHECK(!*called);
pending.dispose();
advance_time(1s);
sched.run();
CHECK(!*called);
}
}
}
GIVEN("a typed actor") {
WHEN("the actor schedules an action with run_delayed") {
THEN("the action triggers after the relative timeout") {
auto called = std::make_shared<bool>(false);
auto aut = spawn_int_actor([called](int_actor_ptr self) {
self->run_delayed(1s, [called] { *called = true; });
});
sched.run();
CHECK(!*called);
advance_time(1s);
sched.run();
CHECK(*called);
}
AND_THEN("disposing the pending timeout cancels the action") {
auto called = std::make_shared<bool>(false);
auto pending = disposable{};
auto aut = spawn_int_actor([called, &pending](int_actor_ptr self) {
pending = self->run_delayed(1s, [called] { *called = true; });
});
sched.run();
CHECK(!*called);
......@@ -65,7 +122,7 @@ SCENARIO("run_delayed_weak triggers an action after a relative timeout") {
auto called = std::make_shared<bool>(false);
auto aut = sys.spawn([called](event_based_actor* self) {
self->run_delayed_weak(1s, [called] { *called = true; });
return dummy_behavior();
return int_behavior();
});
sched.run();
CHECK(!*called);
......@@ -77,7 +134,7 @@ SCENARIO("run_delayed_weak triggers an action after a relative timeout") {
auto called = std::make_shared<bool>(false);
sys.spawn([called](event_based_actor* self) {
self->run_delayed_weak(1s, [called] { *called = true; });
return dummy_behavior();
return int_behavior();
});
sched.run(); // Note: actor cleaned up after this line.
CHECK(!*called);
......@@ -90,7 +147,46 @@ SCENARIO("run_delayed_weak triggers an action after a relative timeout") {
auto pending = disposable{};
auto aut = sys.spawn([called, &pending](event_based_actor* self) {
pending = self->run_delayed_weak(1s, [called] { *called = true; });
return dummy_behavior();
return int_behavior();
});
sched.run();
CHECK(!*called);
pending.dispose();
advance_time(1s);
sched.run();
CHECK(!*called);
}
}
}
GIVEN("a typed actor") {
WHEN("the actor schedules an action with run_delayed") {
THEN("the action triggers after the relative timeout for live actors") {
auto called = std::make_shared<bool>(false);
auto aut = spawn_int_actor([called](int_actor_ptr self) {
self->run_delayed_weak(1s, [called] { *called = true; });
});
sched.run();
CHECK(!*called);
advance_time(1s);
sched.run();
CHECK(*called);
}
AND_THEN("no action triggers for terminated actors") {
auto called = std::make_shared<bool>(false);
spawn_int_actor([called](int_actor_ptr self) {
self->run_delayed_weak(1s, [called] { *called = true; });
});
sched.run(); // Note: actor cleaned up after this line.
CHECK(!*called);
advance_time(1s);
sched.run();
CHECK(!*called);
}
AND_THEN("disposing the pending timeout cancels the action") {
auto called = std::make_shared<bool>(false);
auto pending = disposable{};
auto aut = spawn_int_actor([called, &pending](int_actor_ptr self) {
pending = self->run_delayed_weak(1s, [called] { *called = true; });
});
sched.run();
CHECK(!*called);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment