Модели акторов в С++
миф или реальность
Боргардт Александр Александрович
https://github.com/smart-cloud
What is in the report:
1. The general concept of the actor model;
2. Consider the example of a solved problem with Productions;
3. The internal device of the actor;
4. A little about the life cycle of threadpool;
5. About Different strategies work threadpool.
Mytholog
y
Mytholog
y
Intro
Intro Project Architecture
Smart Proxy Smart Proxy Smart Proxy Smart Proxy
Nginx Nginx Nginx
Service Service Service ServiceService
Client Client Client
Smart Proxy
Other
Service
Service
Statistic
Shard1
Service
User
Service
Statistic
Shard N
Queue
db
CACHE
Intro Part of the project Architecture
Intro The components that hold the system
EventLoop
db
EventLoop
queue
EventLoop
network
ThreadPool
1 2 3 4
PipeLine
PipeLine
PipeLine
PipeLine
PipeLine
Intro
● Single Thread -> Nodejs, python3.4+
● Actor model -> Erlang, Elixir, jvm family, C#
● Communicating sequential processes -> go
● Software transactional memory -> clojure
● etc ...
What models of concurrent programming are?
Actor Model what kind of animal?
Formally, the description of the actor model
It has an ID on which the actor can be identified by other actors;
May interact with other actors only by sending messages with the identifiers of
the actors addresses;
Implements its behavior depending on the incoming messages;
May create one or more new actors;
Can change its state;
Can terminate its execution.
https://en.wikipedia.org/wiki/Actor_model
Actor Model
Actor
C++
OPP
Smalltalk
Class ≈ ≠
What looks like an actor?
What are the implementation?
C++ Actor Framework: CAF
https://www.actor-framework.org/
CAF -> КАФ
SObjectizer
https://github.com/eao197/so-5-5
SObjectizer -> собжектайзер
Message
Async
Send
ThreadPool
Environment
General Schematic
Actor
One of the main ideas of the actor model
Actor
Actor
Actor
Message
Message
Message
One of the main ideas of the actor model
Actorping {};
request response
pong {};
does_not_understand{};Actorother_method{};
Analogy
Browse service
http://mysuperservice.ru/update?d=1&ds=3
Supervisor
Supervisord
Case : restored after the fall of the actor
Time
Supervisord Supervisord
Supervisor
Case : balancing messaging
Supervisord
MSG
Time
Supervisor
Analogy
Browse
Description of a problem Productions
Counters
Json
User service
Case 1:
We obtain the unique identifier and increase the counter by one
Case 2:
Return a list of all the stored hash from uid and the counter
service
Description of possible types of messages.
ActorCounters
put {
string
};
get_all {};
request response
get_all {
vector<string,std::size_t>
};
put {};
does_not_understand{};
ActorCounters
ActorCountersother_method{};
Scheme of the initial solution
Dispatcher
Counters
gen-hash
Broker
IO
Client
Driving the initial decision to supervisord
Supervisord
Counters
Supervisord
gen-hash
Broker
IO
Counters
gen-hash
Client
Client
Client
Supervisord
Counters
Supervisord
gen-hash
Broker
IO
Supervisord
Counters
Counters
Counters
Counters
gen-hash
Counters
Driving the initial decision to supervisord
General Schematic
Environment
Actor Actor
Actor Actor
cooperation
ThreadPool
Actor
state
events loop
User
Method
Actor
state
events loop
User
Method
Data locality and Isolated
HashMap
Message(“update”,{1,1,2})
Actor
Data locality and Isolated
HashMap
HashMap
HashMap
Message(“get”)
Message(“merge”, )
Shared State
Data locality and Isolated Shared State
HashMap
HashMap
Message(“get”)
Message(“merge”, hm*) or Message(“merge”, hm&)
Actor
state
events loop
User
Method
Queue …
Un-bound Queue ????
System + Un-bound Queue
≈
Key word:Queueing theory
Un-bound Queue in Your systems
Un-bound Queue in Your systems
...
Size ?
Size ?
Actor
state
events loop
User
Method
EventLoop in Actor blocking approach
void run(args ..., args ...,) {
message *msg_ptr = nullptr;
while (has_next_message()) {
msg_ptr = next_message();
if (msg_ptr != nullptr) {
***************************************
auto response = life.invoke(msg_ptr);
***************************************
} else {
***************************************
}
}
EventLoop in Actor Pseudo non-blocking
auto run(args ..., size_t max_throughput, args ...,) -> event_type {
message *msg_ptr = nullptr;
for (size_t handled_msgs = 0; handled_msgs < max_throughput;) {
msg_ptr = next_message();
if (msg_ptr != nullptr) {
************************************
auto response = life.invoke(request);
************************************
++handled_msgs;
************************************
} else {
return executable_result::awaiting;
}
}
return executable_result::resume;
}
EventLoop in Actor Pseudo non-blocking
auto run(args ..., size_tmax_throughput, args ...,) -> event_type {
message *msg_ptr = nullptr;
for (size_t handled_msgs = 0; handled_msgs < max_throughput;) {
msg_ptr = next_message();
if (msg_ptr != nullptr) {
************************************
auto response = life.invoke(request);
************************************
++handled_msgs;
************************************
} else {
return executable_result::awaiting;
}
}
return executable_result::resume;
}
struct magick_method final : public abstract_action {
***********************************
response *operator()(request *msg) override final {
***********************************
a lot of data processing
***********************************
return nullptr;
}
};
EventLoop in Actor Pseudo non-blocking
EventLoop in RunOnce
auto run_once(args ..., args ...,) {
return run(args ..., 1, args ...,)
}
How to run once?
General Schematic
Environment
Actor Actor
Actor Actor
cooperation
ThreadPool
EventLoop in Actor System
Job Shared Queue
Worker Worker Worker
Strategy: shared-work
EventLoop in Actor System
Strategy: shared-work
EventLoop in Actor System
EventLoop in Actor System
asynchronous synchronous
proactive Work-balancing Work-distribution
reactive Work-stealing Work-requesting
And what are the tasks scheduling strategy?
EventLoop in Actor System
asynchronous synchronous
proactive Work-balancing Work-distribution
reactive Work-stealing Work-requesting
And what are the tasks scheduling strategy?
EventLoop in Actor System
asynchronous synchronous
proactive Work-balancing Work-distribution
reactive Work-stealing Work-requesting
SCHEDULER = (STEALING ^ REQUESTING) [+DISTRIBUTION] [+BALANCING]
Reality
Possible applications:
● back-end game dev;
● micro-service;
● service;
● macro-service;
● distribution system;
● etc … .
? Questions ?
abstarct_actor
local_actor
scheduler_actor
actor
bloking_actor
group
cooperation
Bonus slide
Inheritance Hierarchy
abstract_actor*
The hierarchy of nesting
What do you want to change?
abstarct_actor
local_actor
template<ParentActor=local_actor, Supervisor=base_supervisor, async=true >
scheduler_actor: public ParentActor,
public Supervisor,
public executable{};
base_supervisor vs fake_supervisor Pseudo non-blocking aka async vs blocking
Bonus slide
Urls:
http://www.ponylang.org/
http://junior.highload.ru/2015/#301215
http://www.highload.ru/2015/abstracts/1964.html
https://en.wikipedia.org/wiki/Actor_model
https://en.wikipedia.org/wiki/Work_stealing
http://www.1024cores.net
http://www.slideshare.net/gpadovani/c-actor-model
https://habrahabr.ru/post/216049/

модели акторов в с++ миф или реальность