Split Actor.is_lite to need_context and need_start_up.

This commit is contained in:
levlam 2021-11-03 15:10:43 +03:00
parent ffa48e523a
commit 6a5b0506e5
7 changed files with 55 additions and 34 deletions

View File

@ -18,25 +18,34 @@
#pragma comment(linker, "/STACK:16777216") #pragma comment(linker, "/STACK:16777216")
#endif #endif
struct TestActor final : public td::Actor {
static td::int32 actor_count_;
void start_up() final {
actor_count_++;
stop();
}
void tear_down() final {
if (--actor_count_ == 0) {
td::Scheduler::instance()->finish();
}
}
};
td::int32 TestActor::actor_count_;
template <>
class td::ActorTraits<TestActor> {
public:
static constexpr bool need_context = false;
static constexpr bool need_start_up = true;
};
class CreateActorBench final : public td::Benchmark { class CreateActorBench final : public td::Benchmark {
private: private:
td::ConcurrentScheduler scheduler_; td::ConcurrentScheduler scheduler_;
struct TestActor final : public td::Actor {
static td::int32 actor_count_;
void start_up() final {
actor_count_++;
stop();
}
void tear_down() final {
if (--actor_count_ == 0) {
td::Scheduler::instance()->finish();
}
}
};
void start_up() final { void start_up() final {
scheduler_.init(0); scheduler_.init(0);
scheduler_.start(); scheduler_.start();
@ -61,8 +70,6 @@ class CreateActorBench final : public td::Benchmark {
} }
}; };
td::int32 CreateActorBench::TestActor::actor_count_;
template <int type> template <int type>
class RingBench final : public td::Benchmark { class RingBench final : public td::Benchmark {
public: public:

View File

@ -469,7 +469,8 @@ class PromiseActor;
template <class T> template <class T>
class ActorTraits<FutureActor<T>> { class ActorTraits<FutureActor<T>> {
public: public:
static constexpr bool is_lite = true; static constexpr bool need_context = false;
static constexpr bool need_start_up = false;
}; };
template <class T> template <class T>

View File

@ -115,7 +115,8 @@ class Actor : public ObserverBase {
template <class ActorT> template <class ActorT>
class ActorTraits { class ActorTraits {
public: public:
static constexpr bool is_lite = false; static constexpr bool need_context = true;
static constexpr bool need_start_up = true;
}; };
} // namespace td } // namespace td

View File

@ -63,7 +63,7 @@ class ActorInfo final
ActorInfo &operator=(const ActorInfo &) = delete; ActorInfo &operator=(const ActorInfo &) = delete;
void init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::OwnerPtr &&this_ptr, Actor *actor_ptr, Deleter deleter, void init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::OwnerPtr &&this_ptr, Actor *actor_ptr, Deleter deleter,
bool is_lite); bool need_context, bool need_start_up);
void on_actor_moved(Actor *actor_new_ptr); void on_actor_moved(Actor *actor_new_ptr);
template <class ActorT> template <class ActorT>
@ -105,7 +105,8 @@ class ActorInfo final
vector<Event> mailbox_; vector<Event> mailbox_;
bool is_lite() const; bool need_context() const;
bool need_start_up() const;
void set_wait_generation(uint32 wait_generation); void set_wait_generation(uint32 wait_generation);
bool must_wait(uint32 wait_generation) const; bool must_wait(uint32 wait_generation) const;
@ -113,7 +114,8 @@ class ActorInfo final
private: private:
Deleter deleter_ = Deleter::None; Deleter deleter_ = Deleter::None;
bool is_lite_ = false; bool need_context_ = true;
bool need_start_up_ = true;
bool is_running_ = false; bool is_running_ = false;
bool always_wait_for_mailbox_{false}; bool always_wait_for_mailbox_{false};
uint32 wait_generation_{0}; uint32 wait_generation_{0};

View File

@ -32,13 +32,13 @@ inline StringBuilder &operator<<(StringBuilder &sb, const ActorInfo &info) {
} }
inline void ActorInfo::init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::OwnerPtr &&this_ptr, Actor *actor_ptr, inline void ActorInfo::init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::OwnerPtr &&this_ptr, Actor *actor_ptr,
Deleter deleter, bool is_lite) { Deleter deleter, bool need_context, bool need_start_up) {
CHECK(!is_running()); CHECK(!is_running());
CHECK(!is_migrating()); CHECK(!is_migrating());
sched_id_.store(sched_id, std::memory_order_relaxed); sched_id_.store(sched_id, std::memory_order_relaxed);
actor_ = actor_ptr; actor_ = actor_ptr;
if (!is_lite) { if (need_context) {
context_ = Scheduler::context()->this_ptr_.lock(); context_ = Scheduler::context()->this_ptr_.lock();
VLOG(actor) << "Set context " << context_.get() << " for " << name; VLOG(actor) << "Set context " << context_.get() << " for " << name;
} }
@ -48,22 +48,32 @@ inline void ActorInfo::init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::O
actor_->init(std::move(this_ptr)); actor_->init(std::move(this_ptr));
deleter_ = deleter; deleter_ = deleter;
is_lite_ = is_lite; need_context_ = need_context;
need_start_up_ = need_start_up;
is_running_ = false; is_running_ = false;
wait_generation_ = 0; wait_generation_ = 0;
} }
inline bool ActorInfo::is_lite() const {
return is_lite_; inline bool ActorInfo::need_context() const {
return need_context_;
} }
inline bool ActorInfo::need_start_up() const {
return need_start_up_;
}
inline void ActorInfo::set_wait_generation(uint32 wait_generation) { inline void ActorInfo::set_wait_generation(uint32 wait_generation) {
wait_generation_ = wait_generation; wait_generation_ = wait_generation;
} }
inline bool ActorInfo::must_wait(uint32 wait_generation) const { inline bool ActorInfo::must_wait(uint32 wait_generation) const {
return wait_generation_ == wait_generation || (always_wait_for_mailbox_ && !mailbox_.empty()); return wait_generation_ == wait_generation || (always_wait_for_mailbox_ && !mailbox_.empty());
} }
inline void ActorInfo::always_wait_for_mailbox() { inline void ActorInfo::always_wait_for_mailbox() {
always_wait_for_mailbox_ = true; always_wait_for_mailbox_ = true;
} }
inline void ActorInfo::on_actor_moved(Actor *actor_new_ptr) { inline void ActorInfo::on_actor_moved(Actor *actor_new_ptr) {
actor_ = actor_new_ptr; actor_ = actor_new_ptr;
} }

View File

@ -168,10 +168,10 @@ EventGuard::~EventGuard() {
} }
info->finish_run(); info->finish_run();
swap_context(info); swap_context(info);
CHECK(info->is_lite() || save_context_ == info->get_context()); CHECK(!info->need_context() || save_context_ == info->get_context());
#ifdef TD_DEBUG #ifdef TD_DEBUG
LOG_CHECK(info->is_lite() || save_log_tag2_ == info->get_name().c_str()) LOG_CHECK(!info->need_context() || save_log_tag2_ == info->get_name().c_str())
<< info->is_lite() << " " << info->empty() << " " << info->is_migrating() << " " << save_log_tag2_ << " " << info->need_context() << " " << info->empty() << " " << info->is_migrating() << " " << save_log_tag2_ << " "
<< info->get_name() << " " << scheduler_->close_flag_; << info->get_name() << " " << scheduler_->close_flag_;
#endif #endif
if (event_context_.flags & Scheduler::EventContext::Stop) { if (event_context_.flags & Scheduler::EventContext::Stop) {
@ -186,7 +186,7 @@ EventGuard::~EventGuard() {
void EventGuard::swap_context(ActorInfo *info) { void EventGuard::swap_context(ActorInfo *info) {
std::swap(scheduler_->event_context_ptr_, event_context_ptr_); std::swap(scheduler_->event_context_ptr_, event_context_ptr_);
if (info->is_lite()) { if (!info->need_context()) {
return; return;
} }
@ -353,7 +353,7 @@ void Scheduler::do_stop_actor(ActorInfo *actor_info) {
CHECK(!actor_info->is_migrating()); CHECK(!actor_info->is_migrating());
LOG_CHECK(actor_info->migrate_dest() == sched_id_) << actor_info->migrate_dest() << " " << sched_id_; LOG_CHECK(actor_info->migrate_dest() == sched_id_) << actor_info->migrate_dest() << " " << sched_id_;
ObjectPool<ActorInfo>::OwnerPtr owner_ptr; ObjectPool<ActorInfo>::OwnerPtr owner_ptr;
if (!actor_info->is_lite()) { if (actor_info->need_start_up()) {
EventGuard guard(this, actor_info); EventGuard guard(this, actor_info);
do_event(actor_info, Event::stop()); do_event(actor_info, Event::stop());
owner_ptr = actor_info->get_actor_unsafe()->clear(); owner_ptr = actor_info->get_actor_unsafe()->clear();

View File

@ -109,7 +109,7 @@ ActorOwn<ActorT> Scheduler::register_actor_impl(Slice name, ActorT *actor_ptr, A
auto weak_info = info.get_weak(); auto weak_info = info.get_weak();
auto actor_info = info.get(); auto actor_info = info.get();
actor_info->init(sched_id_, name, std::move(info), static_cast<Actor *>(actor_ptr), deleter, actor_info->init(sched_id_, name, std::move(info), static_cast<Actor *>(actor_ptr), deleter,
ActorTraits<ActorT>::is_lite); ActorTraits<ActorT>::need_context, ActorTraits<ActorT>::need_start_up);
ActorId<ActorT> actor_id = weak_info->actor_id(actor_ptr); ActorId<ActorT> actor_id = weak_info->actor_id(actor_ptr);
if (sched_id != sched_id_) { if (sched_id != sched_id_) {
@ -117,7 +117,7 @@ ActorOwn<ActorT> Scheduler::register_actor_impl(Slice name, ActorT *actor_ptr, A
do_migrate_actor(actor_info, sched_id); do_migrate_actor(actor_info, sched_id);
} else { } else {
pending_actors_list_.put(weak_info->get_list_node()); pending_actors_list_.put(weak_info->get_list_node());
if (!ActorTraits<ActorT>::is_lite) { if (ActorTraits<ActorT>::need_start_up) {
send<ActorSendType::LaterWeak>(actor_id, Event::start()); send<ActorSendType::LaterWeak>(actor_id, Event::start());
} }
} }