Home

A C++ framework for actor programming User Manual

image

Contents

1. wait until all other actors we ve spawned are done await_all_actors_done shutdown 49 APPENDIX 20 3 Migration Guides The guides in this section document all possibly breaking changes in the library for that last versions of CAF 20 3 1 0 8 gt 0 9 Version 0 9 included a lot of changes and improvements in its implementation but it also made breaking changes to the API self has been removed This is the biggest library change since the initial release The major problem with this keyword like identifier is that it must have a single type as it s implemented as a thread local variable Since there are so many different kinds of actors event based or blocking untyped or typed self needs to perform type erasure at some point rendering it ultimately useless Instead of a thread local pointer you can now use the first argument in functor based actors to catch the self pointer with proper type information actor_ptr has been replaced CAF now distinguishes between handles to actors i e typed_actor lt gt or simply actor and addresses of actors i e actor_addr The reason for this change is that each actor has a logical network wide unique address which is used by the networking layer of CAF Fur thermore for monitoring or linking the address is all you need However the address is not sufficient for sending messages because it doesn t have any type information The function las
2. i 3 Similar to become the then function modifies an actor s behavior stack However it is used as one shot handler and automatically returns to the previous behavior afterwards 19 SYNCHRONOUS COMMUNICATION 7 3 Synchronous Failures and Error Handlers An unexpected response message e a message that is not handled by the one shot handler is considered as an error The runtime will invoke the actor s on_sync_failure which kills the actor by calling sel f gt quit exit_reason unhandled_sync_failure per default The error handler can be overridden by calling sel f gt on_sync_failure as shown below void foo event_based_actorx self actor testee set handler for unexpected messages self gt on_sync_failure aout self lt lt received unexpected synchronous response lt lt to_string self gt last_dequeued lt lt endl set response handler by using then sync_send testee get_atom value then const std string amp str x handle str x any other result will call the on_sync_failure handler i 20 MANAGEMENT amp ERROR DETECTION 8 Management amp Error Detection CAF adapts Erlang s well established fault propagation model It allows to build actor subsystem in which either all actors are alive or have collectively failed 8 1 Links Linked actors monitor each other An
3. BLOCKING API 16 2 Receiving Synchronous Responses Analogous to sync_send then for event based actors blocking actors can use sync_send await void foo blocking_actorx self actor testee testee replies with a string to get self gt sync_send testee get_atom value await e const std stringe str handle str 7 after std chrono seconds 30 gt gt amp handle error 16 3 Mixing Actors and Threads with Scoped Actors The class scoped_actor offers a simple way of communicating with CAF actors from non actor contexts It overloads operator gt to return a blocking_actorx Hence it behaves like the implicit se1 pointer in functor based actors only that it ceases to exist at scope end void test scoped_actor self spawn some monitored actor auto aut self gt spawn lt monitored gt my_actor_impl self gt sync_send aut hi there await handle response i self will be destroyed automatically here any actor monitoring it will receive down messages etc Note that scoped_actor throws an actor_exited exception when forced to quit for some rea son e g Via an exit_msg Whenever a scoped_actor might end up receiving an exit_msg because it links itself to another actor for example the caller either needs to handle the exception or the actor needs to process exit_msg manually via self gt trap_exit true
4. pop_atom gt message auto result data back data pop_back if data empty become empty_ return make_message ok_atom value result i empty_ assign push_atom int what data push_back what become filled_ pop_atom return error_atom value behavior make_behavior override return empty_ size_t max_size std vector lt int gt data behavior full_ behavior filled_ behavior empty_ y 15 RECEIVING MESSAGES 6 2 Nesting Receives Using become unbecome Since become does not block an actor has to manipulate its behavior stack to achieve nested receive operations An actor can set a new behavior by calling become with the keep_behavior policy to be able to return to its previous behavior later on by calling unbecome as shown in the example below receives int float sequences behavior testee event_based_actorx self return int valuel self gt become the keep_behavior policy stores the current behavior on the behavior stack to be able to return to this behavior later on by calling unbecome keep_behavior float value2 cout lt lt valuel lt lt gt lt lt value2 lt lt endl restore previous behavior self gt unbecome An event based actor finishes execution with normal exit reason if the behavior stack is empty after calling unbecome The default policy of become i
5. f gt become pong_value int i if i gt 10 self gt quit return self gt send pong ping_atom value i 1 26 NETWORK IO 12 Network lO When communicating to other services in the network sometimes low level socket IO is inevitable For this reason CAF provides brokers A broker is an event based actor running in the middleman that multiplexes socket lO It can maintain any number of acceptors and connections Since the broker runs in the middleman implementations should be careful to consume as little time as possible in message handlers Any considerable amount work should outsourced by spawning new actors or maintaining worker actors All functions shown in this section can be accessed by including the header caf io all hpp and live in the namespace caf io 12 1 Spawning Brokers Brokers are spawned using the function spawn_io and always use functor based implementa tions capturing the self pointer of type broker For convenience spawn_io_server can be used to spawn a new broker listening to a local port and spawn_io_client can be used to spawn a new broker that connects to given host and port or uses existing lO streams template lt spawn_options Os no_spawn_options typename F std function lt behavior brokerx gt typename Ts gt actor spawn_io F fun Ts amp amp args template lt spawn_options Os no_spawn_options typename F std function lt beh
6. 32 32 34 35 35 36 36 38 38 39 39 40 42 42 43 44 45 46 46 46 46 47 47 48 20 1 Class GPE TON midi id cn de de A A 2S 48 pas 49 20 3 Migration Guides boss neh oe see oes na AA 50 20 3 1 08 S 0 i s ae ah he oS ap ERA A A 50 20 3 2 0 9 gt 0 10 1 i beppa CAF i sd aches aod Ake ack fd AREA Ee ha 51 20 3 3 0 10 ASI amp oe hee 52 203 4001 SONA ed BES heed Eee EDS SESS EES SERS BS 53 ARA Oe 6k add head Ee OE BEE BES ES SERS ES 53 20 3 6 0 135014 2 2 e o 2 ee 53 INTRODUCTION 1 Introduction Before diving into the API of CAF we would like to take the opportunity to discuss the concepts behind CAF and to explain the terminology used in this manual 1 1 Actor Model The actor model describes concurrent entities actors that do not share state and communicate only via message passing By decoupling concurrently running software components via message passing the actor model avoids race conditions by design Actors can create spawn new actors and monitor each other to build fault tolerant hierarchical systems Since message passing is network transparent the actor model applies to both concurrency and distribution When dealing with dozens of cores mutexes semaphores and other threading primitives are the wrong level of abstraction Implementing applications on top of those primitives has proven challenging and error prone Additionally mutex based implementations ca
7. self gt receiv on lt int gt gt gt i The code snippet above illustrates the use of receive Note that the message handler passed to receive is a temporary object at runtime Hence using receive inside a loop would cause creation of a new handler on each iteration CAF provides three predefined receive loops to provide a more efficient but yet convenient way of defining receive loops 36 BLOCKING API DON T DO For 33 receive_loop receive ae y y std vector lt int gt results std vector lt int gt results for size_t i 0 i lt 10 i size t i 0 receive receive_for i 10 on lt int gt gt gt amp int value on lt int gt gt gt amp int value results push_back value results push_back value i size_t received 0 size_t received 0 do do_receive receive others gt gt amp others gt gt amp received received until amp return received gt 10 y while received lt 10 The examples above illustrate the correct usage of the three loops receive_loop receive_for and do_receive until ltis possible to nest receives and receive loops self gt receive_loop on lt int gt gt gt amp int valuel self gt receive on lt float gt gt gt amp float value2 cout lt lt valuel lt lt gt lt lt value2 lt lt endl 37
8. void close connection_handle hdl Closes a connection void close accept_handle hdl Closes an acceptor 28 NETWORK IO 12 3 Broker related Message Types Brokers receive system messages directly from the middleman whenever an event on one of it handles occurs struct new_connection_msg accept_handle source connection_handle handle y Whenever a new incoming connection identified by the handle field has been accepted for one of the broker s accept handles it will receive a new_connection_msg struct new_data_msg connection _handle handle std vector lt char gt buf y New incoming data is transmitted to the broker using messages of type new_data_msg The raw bytes can be accessed as buffer object of type std vector lt char gt The amount of data i e how often this message is received can be controlled using configure_read see 12 2 It is worth mentioning that the buffer is re used whenever possible This means as long as the broker does not create any new references to the message by copying it the middleman will always use only a single buffer per connection struct connection_closed_msg connection_handle handle hi struct acceptor_closed_msg accept_handle handle y A connection_closed_msg of acceptor_closed_msg informs the broker that one of it handles is no longer valid 29 GROUP COMMUNICATION 13 Group Communication CAF supports publish subscribe based g
9. pr b hy const shutdown_request self gt quit class typed_calculator_class public calculator_type base protected behavior_type make_behavior override return const plus_request amp pr return pr a pr b 7 const minus_request amp pr yetur pra pr b const shutdown_request quit y 40 STRONGLY TYPED ACTORS void tester event_based_actor self const calculator_type amp testee int self gt link_to testee will be invoked if we receive an unexpected response message self gt on_sync_failure aout self lt lt AUT actor under test failed lt lt endl self gt quit exit_reason user_shutdown PD first test 2 1 3 self gt sync_send testee plus_request 2 1 then int r1 assert rl 3 second test 2 1 1 self gt sync_send testee minus_request 2 1 then IAE re 1 assert r2 1 both tests succeeded aout self lt lt AUT actor under test lt lt seems to be ok lt lt endl self gt send testee shutdown_request 5 main announce custom message types announce lt shutdown_request gt shutdown_request announce lt plus_request gt plus_request plus_request a amp plus_request b announce lt minus_request gt minus_request minus_request a minus_request b test function based impl s
10. 38 STRONGLY TYPED ACTORS 17 Strongly Typed Actors Strongly typed actors provide a convenient way of defining type safe messaging interfaces Unlike untyped actorsd typed actors are not allowed to use guard expressions When calling become in a strongly typed actor all message handlers from the typed interface must be set Typed actors use handles of type typed_actor lt gt rather than actor whereas the template parameters hold the messaging interface For example an actor responding to two integers with a dobule would use the type typed_actor lt replies_to lt int int gt with lt double gt gt All functions for message passing linking and monitoring are overloaded to accept both types of actors 17 1 Spawning Typed Actors Typed actors are spawned using the function spawn_typed The argument to this function call must be a match expression as shown in the example below because the runtime of CAF needs to evaluate the signature of each message handler auto p0 spawn_typed int a int b return static_cast lt double gt a x b double a double b return std make_tuple a b a b y assign to identical type using full_type typed_actor lt replies_to lt int int gt with lt double gt replies_to lt double double gt with lt double double gt gt full_type pl p0 assign to subtype using subtypel typed_actor lt replies_to lt int int gt with lt double gt gt subtypel
11. actor sends an exit message to all of its links as part of its termination The default behavior for actors receiving such an exit message is to die for the same reason if the exit reason is non normal Actors can trap exit messages to handle them manually actor worker receive exit messages as regular messages self gt trap_exit true monitor spawned actor self gt link_to worker wait until worker exited self gt become const exit_msgg e if e reason exit_reason normal worker finished computation else worker died unexpectedly 8 2 Monitors A monitor observes the lifetime of an actor Monitored actors send a down message to all ob servers as part of their termination Unlike exit messages down messages are always treated like any other ordinary message An actor will receive one down message for each time it called self gt monitor even if it adds a monitor to the same actor multiple times actor worker monitor spawned actor self gt monitor worker wait until worker exited self gt become const down_msg amp d ma if d reason exit_reason normal worker finished computation else worker died unexpectedly 21 MANAGEMENT amp ERROR DETECTION 8 3 Error Codes All error codes are defined in the namespace caf exit_reason To obtain a string represen tation of an error code use caf exit_
12. bound port as return value The return value is equal to port if port 0 The function throws network_error if socket related errors occur or bind_failure if the specified port is already in use The optional addr parameter can be used to listen only to the given address Otherwise the actor accepts all incoming connections INADDR_ANY The flag reuse_addr controls the behavior when binding an IP address to a port with the same semantics as the BSD socket flag SO_REUSEADDR For example if reuse_addr false binding two sockets to 0 0 0 0 42 and 10 0 0 1 42 will fail with EADDRINUSE since 0 0 0 0 includes 10 0 0 1 With reuse_addr true binding would succeed because 10 0 0 1 and 0 0 0 0 are not literally equal addresses publish self 4242 self gt become ping_atom int i return std make_tuple pong_atom value i m i To close a socket e g to allow other actors to be published at the port the function unpublish can be used This function is called implicitly if a published actor terminates void unpublish caf actor whom uint16_t port 25 NETWORK TRANSPARENCY 11 2 Connecting to Remote Actors actor remote_actor const charx host std uint16_t port The function remote_actor connects to the actor at given host and port A network_error is thrown if the connection failed auto pong remote_actor localhost 4242 sel sel f gt send pong ping_atom value 0
13. implementation detail of message and should not live in the global namespace in the first place It also had the wrong name because it is intrusive X gt message_builder This new class can be used to create mes sages dynamically For example the content of a vector can be used to create a message using a series of append calls accept_handle connection_handle publish max_msg_size typed_remote_actor publish_local_groups new_connection_msg new_data_msg connection_closed_msg acceptor_closed_msg remote_actor typed_publish These classes concern I O functionality and have thus been moved to caf io 20 3 3 0 10 0 11 Version 0 11 introduced new optional components The core library itself however mainly re ceived optimizations and bugfixes with one exception the member function on_exit is no longer virtual You can still provide it to define a custom exit handler but you must not use override 32 APPENDIX 20 3 4 0 11 gt 0 12 Version 0 12 removed two features e Type names are no longer demangled automatically Hence users must explicitly pass the type name as first argument when using announce i e announce lt my_class gt becomes announce lt my_class gt my_class e Synchronous send blocks no longer support continue_with This feature has been removed without substitution 20 3 5 0 12 gt 0 13 This release removes the since 0 9 deprecated cppa header
14. of actor B and thus could recognize the forwarding by evaluating self gt last_sender 13 RECEIVING MESSAGES 6 Receiving Messages The current behavior of an actor is its response to the next incoming message and includes a sending messages to other actors b creation of more actors and c setting a new behavior An event based actor i e the default implementation in CAF uses become to set its behavior The given behavior is then executed until it is replaced by another call to become or the actor finishes execution 6 1 Class based actors A class based actor is a subtype of event_based_actor and must implement the pure virtual member function make_behavior returning the initial behavior class printer public event_based_actor behavior make_behavior override return others gt gt cout lt lt to_string last_dequeued lt lt endl 14 RECEIVING MESSAGES using pop_atom atom_constant lt atom pop gt using push_atom atom_constant lt atom push gt class fixed_stack public event_based_actor public fixed_stack size_t max max_size max full_ assign push_atom int j discard pop_atom gt message auto result data back data pop_back become filled_ return make_message ok_atom value result y filled_ assign push_atom int what data push_back what if data size max_size become full_
15. p2 pod assign to another subtype using subtype2 typed_actor lt replies_to lt double double gt with lt double double gt gt subtype2 p3 p0 39 STRONGLY TYPED ACTORS 17 2 Class based Typed Actors Typed actors are spawned using the function spawn_typed and define their message passing interface as list of replies_to lt gt with lt gt statements This interface is used in 1 typed_event_based_actor lt gt which is the base class for typed actors 2 the handle type typed_actor lt gt and 3 typed_behavior lt gt i e the behavior definition for typed actors Since this is rather redundant the actor handle provides definitions for the behavior as well as the base class as shown in the example below It is worth mentioning that all typed actors always use the event based implementation i e there is no typed actor implementation providing a blocking API n truct shutdown_request n truct plus_request int a int b truct minus_request int a int b 10 typedef typed_actor lt replies_to lt plus_request gt with lt int gt replies_to lt minus_request gt with lt int gt replies_to lt shutdown_request gt with lt void gt gt calculator_type calculator_type behavior_type typed_calculator calculator_type pointer self return const plus_request amp pr return pr a pr b hy const minus_request amp pr return pr a
16. CAF A C framework for actor programming User Manual CAF version 0 14 0 Dominik Charousset July 6 2015 Contents 1 Introduction 1 1 Actor Model 1 2 Terminology 1 2 1 Actor Address 1 2 2 Actor Handle 1 2 3 Untyped ACTOS sab fe eb ed ld e ee 1 2 4 Typed Actor 1 2 5 Spawning 1 2 6 Monitoring 127 Links 2 1 Features Overview 2 2 Supported Compilers 2 3 Supported Operating Systems ao oa oao a a 2 4 Hello World Example 3 Pattern Matching 3 1 Basics 3 2 Atoms 3 3 Advanced Match Cases 0 a a ee ee Wild a 3 5 Projections 3 6 Dynamically Building Messages 0 e 4 1 4 2 Implicit se1 f Pointer Interface 5 Sending Messages 9 1 Replying to Messages 10 10 11 12 5 2 Delaying Messages 5 3 Forwarding Messages in Untyped Actors 0 0 e 6 Receiving Messages 6 1 Class based actors 6 2 Nesting Receives Using become unbecoMe o 6 3 Timeouts 6 4 Skipping Messages 7 Synchronous Communication 7 1 Additional Error Messages 2 ee a 7 2 Receive Response Messages ee 7 3 Synchronous Failures and Error Handlers 8 Management amp Error Detection 8 1 Links 8 2 Monitors 8 3 Error Codes 8 4 Attach Cle
17. NICATION 13 4 Spawning Actors in Groups The function spawn_in_group can be used to create actors as members of a group The func tion causes the newly created actors to call join immediately and before spawn_in_group returns The usage of spawn_in_group is equal to spawn except for an additional group argu ment The group handle is always the first argument as shown in the examples below void funl void fun2 int float class my_actorl event_based_actor x class my_actor2 event_based_actor my_actor2 const std string amp str auto grp group get auto al spawn_in_group grp funl auto a2 spawn_in_group grp fun2 1 2 0f auto a3 spawn_in_group lt my_actorl gt grp auto a4 spawn_in_group lt my_actor2 gt grp hello my_actor2 31 MANAGING GROUPS OF WORKERS 14 Managing Groups of Workers When managing a set of workers a central actor often dispatches requests to a set of workers For this purpose the class actor_poo1 implements a lightweight abstraction for managing a set of workers using a dispatching policy Unlike groups pools usually own their workers Pools are created using the static member function make which takes either one argument the policy or three number of workers factory function for workers and dispatching policy After construction one can add new workers via messages of the form S YS PUT wor
18. Options The class message also contains a convenience interface to extract for parsing command line options the member function extract_opts int main int argc char argv uint16_t port string host localhost auto res message_builder argv 1 argv argc extract_opts port p set port port host H set host default localhost host verbose v enable verbose mode if res error empty read invalid CLI arguments cerr lt lt res error lt lt endl return 1 if res opts count help gt 0 f CLI arguments contained h help or 2 builtin cout lt lt res helptext lt lt endl return 0 if res remainder empty res remainder stors all extra arguments that weren t consumed if res opts count verbose gt 0 enable verbose mode if x Output of program_name h Allowed options p pert arg set port H host arg set host default localhost v verbose enable verbose mod 45 COMMON PITFALLS 19 Common Pitfalls 19 1 Defining Patterns e C evaluates comma separated expressions from left to right using only the last element as return type of the whole expression This means that message handlers and behaviors must not be initialized like this message_handler wrong ine DEA Perl Ty loat E 1 kocork y The correct
19. _message Transfers ownership of its data to the new message Warning this function leaves the builder in an in valid state i e calling any member function on it af terwards is undefined behavior 43 MESSAGES 18 3 Extracting The member function message extract removes matched elements from a message x Messages are filtered by repeatedly applying a message handler to the greatest remaining slice whereas slices are generated in the sequence 0 size 0 size 1 1 size 1 size 1 size Whenever a slice is matched it is removed from the message and the next slice starts at the same index on the reduced message For example auto msg make_message 1 2 f 3 f 4 remove float and integer pairs auto msg2 msg extract float float int ant 1 b assert msg2 make_message 1 4 Step by step explanation e Slice 1 1 2 f 3 4 no match e Slice 2 1 2 f 3 no match e Slice 3 1 2 f no match e Slice 4 1 no match e Slice 5 2 f 3 4 no match e Slice 6 2 f 3 match new message is 1 4 e Slice 7 4 no match Slice 7 is 4 i e does not contain the first element because the match on slice 6 occurred at index position 1 The function extract iterates a message only once from left to right The returned message contains the remaining e unmatched elements 44 MESSAGES 18 4 Extracting Command Line
20. anup Code to an Actor eee ee 9 Spawning Actors 10 Message Priorities 11 Network Transparency 11 1 Publishing of Actors 11 2 Connecting to Remote Actors s 2435465435 46 da6 64 4 4845 8 4 12 1 Spawning Brokers 12 2 Broker Interface 12 3 Broker related Message Types e 2 2 13 Group Communication 13 1 Anonymous Groups 14 14 16 17 18 19 19 19 20 21 21 21 22 22 23 24 25 25 26 27 27 28 29 30 13 2 Local Groups 13 3 Remote Groups 13 4 Spawning Actors in Groups 14 Managing Groups of Workers 14 1 Dispatching Policies 14 2 Example oe se ee eke ba 15 Platform Independent Type System 15 1 User Defined Data Types in Messages 222004 16 Blocking API 16 1 Receiving Messages 16 2 Receiving Synchronous Responses 2 05 0502s 16 3 Mixing Actors and Threads with Scoped Actors 17 Strongly Typed Actors 17 1 Spawning Typed Actors 17 2 Class based Typed Actors 18 Messages 18 1 Classmessage 18 2 Class message_builder 18 3 Extracting lt 0 4 4 x 18 4 Extracting Command Line Options 19 1 Defining Patterns 19 2 Event Based API 19 3 Synchronous Messages 19 4 Sharing 19 5 Constructors of Class based Actors 20 Appendix
21. avior brokerx gt typename Ts gt actor spawn_io_client F fun input_stream_ptr in output_stream_ptr out TS amp amp args template lt spawn_options Os no_spawn_options typename F std function lt behavior brokerx gt typename Ts gt actor spawn_io_client F fun string host uintl6_t port Ts amp amp args template lt spawn_options Os no_spawn_options typename F std function lt behavior brokerx gt typename Ts gt actor spawn_io_server F fun uintl6_t port Ts amp amp args 27 NETWORK IO 12 2 Broker Interface class broker Member Functions void configure_read connection_handle hdl receive_policy config config Modifies the receive policy for the connection identified by hdl This will cause the middle man to enqueue the next new_data_msg according to the given config created by receive_policy exactly x receive_policy at_most x or receive_policy at_least x with x denoting the number of bytes id LE tion_handle hdl a CENA PLA Writes data to the output buffer size_t num_bytes const void buf void flush connection_handle hdl Sends the data from the output buffer late lt cl Fy 1 tax TS gt eee eee dd j Spawns a new broker that takes ownership of ACRON forks CUR iven connection connection_handle hdl Ts amp amp args 9 size_t num_connections Returns the number of open connections
22. convenience actor_pool policy actor_pool round_robin j This policy forwards incoming requests in a round robin manner to workers There is no guarantee that messages are consumed i e work items are lost if the worker exits before processing all of its messages actor_pool policy actor_pool broadcast This policy forwards each message to all workers Synchronous messages to the pool will be received by all workers but the client will only recognize the first arriving response message or 32 MANAGING GROUPS OF WORKERS error and discard subsequent messages Note that this is not caused by the policy itself but a consequence of forwarding synchronous messages to more than one actor actor_pool policy actor_pool random This policy forwards incoming requests to one worker from the pool chosen uniformly at random Analogous to round_robin this policy does not cache or redispatch messages using join function lt void T messages gt using split function lt void vector lt pair lt actor message gt gt amp message amp gt template lt class T gt static policy split_join join jf split sf T init T This policy models split join or scatter gather work flows where a work item is split into as many tasks as workers are available and then the individuals results are joined together before sending the full result back to the client The join function is responsible for
23. ctor implementations Network transparent messaging Error handling based on Erlang s failure model Pattern matching for messages as internal DSL to ease development Thread mapped actors for soft migration of existing applications Publish subscribe group communication 2 2 Supported Compilers e GCC gt 4 8 e Clang gt 3 2 2 3 Supported Operating Systems e Linux e Mac OS X e Note for MS Windows CAF relies on C 11 features such as unrestricted unions We will support this platform as soon as Microsofts compiler implements all required C 11 features In the meantime CAF can be used with MinGW FIRST STEPS 2 4 Hello World Example include lt string gt include lt iostream gt include caf all hpp using namespace std using namespace caf behavior mirror event_based_actorx self teturn the initial return actor behavior a handler for messages containing a single string that replies with a string const si tring amp what 7 prim thread sal t gt string ts Hello World via aout fe cout wrapper aout self lt lt what terminates this actor become sel f gt quit reply dlroW olien return string what rbegin what rend t lt lt endl otherwise loops forever void hello_world event_based_actorx self const actorg buddy send Hello World to our buddy buddy Hello World then s
24. ed Note It is possible to attach code to remote actors but the cleanup code will run on the local machine 22 SPAWNING ACTORS 9 Spawning Actors Actors are created using the function spawn The easiest way to implement actors is to use func tors e g a free function or a lambda expression The arguments to the functor are passed to spawn as additional arguments The function spawn also takes optional flags as template param eter The flag detached causes spawn to assign a dedicated thread to the actor i e to opt out of the cooperative scheduling Convenience flags like 1inked or monitored automatically link or monitor to the newly created actor Naturally these two flags are not available on top level spawns Actors that make use of the blocking API see Section 16 must be spawned using the flag blocking_api Flags are concatenated using the operator as shown in the examples below include caf all hpp using namespace caf void my_actorl void my_actor2 event_based_actorx int argl void ugly_duckling blocking_actor const std string amp arg2 class my_actor3 public event_based_actor x x class my_actor4 public event_based_actor public my_actor4 int some_value y whenever we want to link to or monitor a spawned actor we have to spawn it using the self pointer we can use the free function spawn top level spawn void ser
25. ed by pointers to all members or getter setter pairs This works for all primitive data types and STL compliant containers See the announce examples 1 4 of the standard distribution for more details Obviously there are limitations You have to implement serialize deserialize by yourself if your class does implement an unsupported data structure See announce_example_5 cpp in the examples folder 35 BLOCKING API 16 Blocking API Besides event based actors the default implementation CAF also provides context switching and thread mapped actors that can make use of the blocking API Those actor implementations are intended to ease migration of existing applications or to implement actors that need to have access to blocking receive primitives for other reasons Event based actors differ in receiving messages from context switching and thread mapped ac tors the former define their behavior as a message handler that is invoked whenever a new messages arrives in the actor s mailbox by using become whereas the latter use an explicit blocking receive function 16 1 Receiving Messages The function receive sequentially iterates over all elements in the mailbox beginning with the first It takes a message handler that is applied to the elements in the mailbox until an element was matched by the handler An actor calling receive is blocked until it successfully dequeued a message from its mailbox or an optional timeout occurs
26. ediate object providing operator gt gt The right hand side of the operator denotes a callback usually a lambda expression that should be invoked if a tuple matches the types given to on When using the basic syntax CAF generates the match case automatically A verbose version of the bhvr1 from 3 1 is shown below behavior verbose_bhvrl o n lt inte gt 1 gt gt 1 Lat 1 Escaso on lt int float gt gt gt int i float f 1 x on lt int Int nte gt O gt gt 1 nt a int by ant c sc It is worth mentioning that passing the lambdas directly is more efficient since it allows CAF to select a special purpose implementation The function on can be used in two ways Either with template parameters only or with function parameters only The latter version deduces all types from its arguments and matches for both type and value To match for any value of a given type the template val lt T gt can be used as shown in the following example behavior bhvr3 on 42 gt gt int i assert i 42 on hello world gt gt x ase on print val lt std string gt gt gt const std string amp what Note The given callback can have less arguments than the pattern But it is only allowed to skip arguments from left to right on lt int float double gt gt gt double x if ok on lt int float double gt gt gt float doub
27. elf gt sync_send EF naa MALE const string what IF sss and print TE aout self lt lt what int main for a response t t lt lt endl create a new actor that calls mirror auto mirror_actor spawn create another actor that calls hello world mirror actor spawn hello_world mirror_actor wait until all await_all_actors_done run cleanup code before exiting main shutdown mirror other actors we have spawned are done PATTERN MATCHING 3 Pattern Matching Actor programming implies a message passing paradigm This means that defining message handlers is a recurring task The easiest and most natural way to specify such message handlers is pattern matching Unfortunately C does not provide any pattern matching facilities Hence we provide an internal domain specific language to match incoming messages 3 1 Basics Actors can store a set of message callbacks using either behavior or message_handler The difference between the two is that the former stores an optional timeout The most basic way to define a pattern is to store a set of lambda expressions using one of the two container types behavior bhvrl T Ane E Regal Fy int i float x x int a int b int c x x In our first example bhvr1 models a pattern accepting messages that consist of either exactly one int or one int followed by a floa
28. ely in a thread pool Thread mapped actors can be used to opt out of this cooperative scheduling 4 1 Implicit self Pointer When using a function or functor to implement an actor the first argument can be used to capture a pointer to the actor itself The type of this pointer is event_based_actor per default and blocking_actorx when using the blocking_api flag When dealing with typed actors the types are typed_event_based_actor lt gt x and typed_blocking_actor lt gt x 10 ACTORS 4 2 Interface class local_actor Member functions Observers actor_addr address Returns the address of this actor bool trap_exit Checks whether this actor traps exit messages messages current_message Returns the currently processed message Warning Only set during callback invocation calling this function after forwarding the message or while not in a callback is undefined behavior actor_addr amp current_sender Returns the sender of the current message Warning Only set during callback invocation calling this function after forwarding the message or while not in a callback is undefined behavior vector lt group gt joined_groups Returns all subscribed groups Modifiers quit uint32_t reason normal Finishes execution of this actor void trap_exit bool enabled Enables or disables trapping of exit messages void join const groups g Subscribes
29. evertheless the recommended way of sharing informations is message passing Sending the same message to multiple actors does not result in copying the data several times 19 5 Constructors of Class based Actors e You should not try to send or receive messages in a constructor or destructor because the actor is not fully initialized at this point 47 APPENDIX 20 Appendix 20 1 Defined Class option in header caf option hpp template lt typename T gt class option Represents an optional value Member types Member type Definition type T Member Functions option Constructs an empty option option T value Initializes this with value option const options option option amp amp Copy move construction option amp operator const option option amp operator option amp amp Copy move assignment Observers bool expli valid cit operator bool Returns true if this has a value poe bool empty operator Returns true if this does not has a value const const T get T amp operator Access stored value const T get_or_else const T amp x Returns get if valid x otherwise Modifiers T amp ge t T operators Access stored value 48 APPENDIX 20 2 Using aout A Concurrency safe Wrapper for cout When using cout from multiple ac
30. glueing all result messages together to create a single result The function is called with the result object initialed using init and the current result messages from a worker The first argument of a split function is a mapping from actors workers to tasks messages The second argument is the input message The default split function is a broadcast dispatching sending each worker the original request 33 MANAGING GROUPS OF WORKERS 14 2 Example actor new_worker return spawn gt behavior return int x int y ESGLUEA x y void broadcast_example scoped_actor self spawns a pool with 5 workers auto pool5 return actor_pool make 5 new_worker actor_pool broadcast y spawns a pool with 5 pools with 5 workers each auto w actor_pool make 5 pool5 actor_pool broadcast will be broadcasted to 25 workers self gt send w 1 2 std vector lt int gt results int i 0 self gt receive_for i 25 amp int res results push_back res 5 assert results size 25 assert std all_of results begin results end int res return res 3 terminate pool s and all workers self gt send_exit w exit_reason user_shutdown 34 PLATFORM INDEPENDENT TYPE SYSTEM 15 Platform Independent Type System CAF provides a fully network transparent communication between actors Thus CAF needs to serialize and deserial
31. hermore it provides implementations or type aliases for renamed or removed classes such as cow_tuple You won t get any warning about deprecated headers with 0 10 However we will add this warnings in the next library version and remove deprecated code eventually Even when using the backwards compatibility header the new library has breaking changes For instance guard expressions have been removed entirely The reasoning behind this decision is that we already have projections to modify the outcome of a match Guard expressions add little expressive power to the library but a whole lot of code that is hard to maintain in the long run due to its complexity Using projections to not only perform type conversions but also to restrict values is the more natural choice The following table summarizes the changes made to the API 51 APPENDIX Change Explanation any_tupl gt messag This type is only being used to pass a message from one actor to another Hence message is the logical name partial_function gt message_handler Technically it still is a partial function but wanted to emphasize its use case in the library cow_tuple gt X We want to provide a streamlined simple API Shipping a full tuple abstraction with the library does not fit into this philosophy The removal of cow_tuple implies the removal of related functions such as tuple_cast cow_ptr gt X This pointer class is an
32. ize messages Unfortunately this is not possible using the RTTI system of C CAF uses its own RTTI based on the class uniform_type_info since it is not possible to extend std type_info Unlike std type_info name uniform_type_info name is guaranteed to return the same name on all supported platforms Furthermore it allows to create an instance of a type by name creates a signed 32 bit integer uniform_value i uniform_typeid lt int gt gt create You should rarely if ever need to use uniform_value or uniform_type_info The type uniform_value stores a type erased pointer along with the associated uniform_type_info The sole purpose of this simple abstraction is to enable the pattern matching engine of CAF to query the type information and then dispatch the value to a message handler When using a message_builder each element is stored as a uniform_value 15 1 User Defined Data Types in Messages All user defined types must be explicitly announced so that CAF can de serialize them correctly as shown in the example below include caf all hpp struct foo int az int bi int main caf announce lt foo gt foo foo a amp f00 b foo can now safely be used in messages Without announcing foo CAF is not able to de serialize instances of it The function announce takes the class as template parameter The first argument to the function always is the type name follow
33. ker remove workers with S YS DELETE worker and retrieve the set of workers as vector lt actor gt via S YS GET For example send my_pool sys_atom value put_atom value worker adds worker to my_pool An actor pool takes ownership of its workers When forced to quit it sends an exit messages to all of its workers forcing them to quit as well The pool also monitors all of its workers Pools do not cache messages but enqueue them directly in a workers mailbox Consequently a terminating worker loses all unprocessed messages For more advanced caching strategies such as reliable message delivery users can implement their own dispatching policies 14 1 Dispatching Policies A dispatching policy is a functor with the following signature using uplock upgrade_lock lt detail shared_spinlock gt using policy std function lt void uplock guard const actor_vec amp workers mailbox_element_ptr ptr execution_unitx host gt The argument guard is a shared lock that can be upgraded for unique access if the policy includes a critical section The second argument is a vector containing all workers managed by the pool The argument pt r contains the full message as received by the pool Finally host is the current scheduler context that can be used to enqueue workers into the corresponding job queue The actor pool class comes with a set predefined policies accessible via factory functions for
34. l characters are _0 9A Za z and the whitespace character Atoms are created using the constexpr function atom as the following example illustrates PATTERN MATCHING w tom add tom multiply atom_value al atom_value a2 II w Warning The compiler cannot enforce the restrictions at compile time except for a length check The assertion atom atom is not true because each invalid character is mapped to the whitespace character An atom_value alone does not help us statically annotate function handlers To accomplish this CAF offers compile time atom constants using add_atom atom_constant lt atom add gt using multiply_atom atom_constant lt atom multiply gt Using the constants we can now define message passing interfaces in a convenient way behavior do_math add_atom int a int b return a b r multiply_atom int a int b return a x b y Atom constants define a static member value that can be used on the caller side see Section 5 e g send math_actor add_atom value 1 2 Please note that the static value member does not have the type atom_value unlike std integral_constant for example PATTERN MATCHING 3 3 Advanced Match Cases Match cases are an advanced feature of CAF and allow you to match on values and to transform data while matching A match case begins with a call to the function on which returns an inter m
35. le ok on lt int float double gt gt gt int float double ok on lt int float double gt gt gt int i compiler error To avoid redundancy when working with match expressions arg_match can be used as last argument to the function on This causes the compiler to deduce all further types from the signature of any given callback on lt int int gt gt gt int a int b x x is equal to on arg_match gt gt int a int b x x Note that arg_match must be passed as last parameter If all types should be deduced from the callback signature on_arg_match can be used which is a faster alternative for on arg_match However on_arg_mat ch is used implicitly whenever a callback is used with out preceding match expression PATTERN MATCHING 3 4 Wildcards The type anything can be used as wildcard to match any number of any types A pattern created by on lt anything gt or its alias others is useful to define a default case For patterns defined without template parameters the constexpr value any_vals can be used as function argument The constant any_vals is of type anything and is nothing but syntactic sugar for defining patterns on lt int anything gt gt gt int i tuple with int as first element Py on any_vals arg_match gt gt int i tuple with int as last element on any_vals arg_match is equal t
36. ly at runtime using a_atom atom_constant lt atom a gt using b_atom atom_constant lt atom b gt behavior testee event_based_actorx self send b with normal priority self gt send self b_atom value send af with high priority self gt send message_priority high self a_atom value terminate after receiving a b return b_atom aout self lt lt received b gt quit lt lt endl self gt quit Fr a_atom aout self lt lt received a lt lt endl by int main will print received b gt quit spawn testee await_all_actors_done fe will print receaved a and then received p gt quit spawn lt priority_aware gt testee await_all_actors_done shutdown 24 NETWORK TRANSPARENCY 11 Network Transparency All actor operations as well as sending messages are network transparent Remote actors are represented by actor proxies that forward all messages All functions shown in this section can be accessed by including the header caf io all hpp and live in the namespace caf io 11 1 Publishing of Actors uint16_t publish actor whom uintl6_t port const char addr nullptr bool reuse_addr false The function publish binds an actor to a given port To choose the next high level port available for binding one can specify port 0 and retrieves the
37. n cause queueing and unmindful access to even distinct data from separate threads in parallel can lead to false sharing both decreasing performance significantly up to the point that an application actually runs slower when adding more cores The actor model has gained momentum over the last decade due to its high level of abstraction and its ability to make efficient use of multicore and multiprocessor machines However the actor model has not yet been widely adopted in the native programming domain With CAF we contribute a library for actor programming in C as open source software to ease native development of concurrent as well as distributed systems In this regard CAF follows the C philosophy building the highest abstraction possible without sacrificing performance 1 2 Terminology You will find that CAF has not simply adopted exiting implementations based on the actor model such as Erlang or the Akka library Instead CAF aims to provide a modern C API allowing for type safe as well as dynamically typed messaging Hence most aspects of our system are familiar to developers having experience with other actor systems but there are also slight differences in terminology However neither CAF nor this manual require any foreknowledge 1 2 1 Actor Address In CAF each actor has a network wide unique logical address that can be used to identify and monitor it However the address can not be used to send a message to an acto
38. o matching message was found CAF supports timeouts using minutes seconds milliseconds and microseconds How ever note that the precision depends on the operating system and your local work load Thus you should not depend on a certain clock resolution 17 RECEIVING MESSAGES 6 4 Skipping Messages Unmatched messages are skipped automatically by CAF s runtime system This is true for all actor implementations To allow actors to skip messages manually skip_message can be used This is in particular useful whenever an actor switches between behaviors but wants to use a default rule created by others to catch messages that are not handled by any of its behaviors The following example illustrates a simple server actor that dispatches requests to workers After receiving an idle message it awaits a request that is then forwarded to the idle worker Afterwards the server returns to its initial behavior e awaits the next idle message The server actor will exit for reason user_defined whenever it receives a message that is neither a request nor an idle message using idle_atom atom_constant lt atom idle gt using request_atom atom_constant lt atom request gt behavior server event_based_actorx self auto die self gt quit exit_reason user_defined return idle_atom auto worker last_sender self gt become keep_behavior request_atom fo
39. o on anything arg_match others gt gt everything else default handler others is equal to on lt anything gt and on any_vals 3 5 Projections Projections perform type conversions or extract data from a given input lf a callback expects an integer but the received message contains a string a projection can be used to perform a type conversion on the fly This conversion must not have side effects and must not throw exceptions A failed projection is not an error it simply indicates that a pattern is not matched Let us have a look at a simple example auto intproj const string str gt option lt int gt charx endptr nullptr int result static_cast lt int gt strtol str c_str amp endptr 10 if endptr nullptr amp amp x endptr 0 return result return message_handler fun on intproj gt gt int 1 case 1 successfully converted a string const string amp str case 2 str is not an integer The lambda intproj is a string gt int projection but note that it does not return an integer It returns opt ion lt int gt because the projection is not guaranteed to always succeed An empty option indicates that a value does not have a valid mapping to an integer A pattern does not match if a projection failed PATTERN MATCHING Note Functors used as projection must take exactly one argument and mus
40. om the first n values message take_right size_t n Creates a new message from the last n values message slice size_t p size_t n Creates a new message from p p n message slice size_t p size_t n Creates a new message from p p n message extract message_handler See 8118 3 message extract_opts See 8 18 4 Modifiers optional lt message gt apply message_handler f Returns f xthis void mutable_at size_t p Returns a pointer to the element at position p template lt class T gt T get_as_mutable size_t p Returns a reference to the element at position p 42 MESSAGES 18 2 Class message builder Member functions Constructors 0 Creates an empty message builder template lt class Iter gt Iter first Iter last Adds all elements from range first last Observers bool empty Returns whether this message is empty size_t size Returns the size of this message message to_message Converts the buffer to an actual message object template lt class T gt append T val Adds val to the buffer template lt class Iter gt append Iter first Iter last Adds all elements from range first last message extract message_handler message extract_opts See 8 18 3 See 18 4 Modifiers optional lt message gt apply message_handler f Returns f xthis message move_to
41. ors monitoring it as part of its termination This allows actors to supervise other actors and to take measures when one of the supervised actors failed e terminated with a non normal exit reason 1 2 7 Links A link is bidirectional connection between two actors Each actor sends an exit message to all of its links as part of its termination Unlike down messages cf 1 2 6 the default behavior for received exit messages causes the receiving actor to terminate for the same reason if the link has failed i e terminated with a non normal exit reason This allows developers to create a set of actors with the guarantee that either all or no actors are alive The default behavior can be overridden i e exit message can be trapped When trapping exit messages they are received as any other ordinary message and can be handled by the actor FIRST STEPS 2 First Steps To compile CAF you will need CMake and a C 11 compiler To get and compile the sources open a terminal on Linux or Mac OS X and type git clone https github com actor framework actor framework cd actor framework configure make make install as root optional It is recommended to run the unit tests as well make test Please submit a bug report that includes a your compiler version b your OS and c the content of the file build Testing Temporary LastTest logif an error occurs 2 1 Features Overview Lightweight fast and efficient a
42. ow behavior client event_based_actorx self const actors master return const string amp request return self gt sync_send master request then const std string amp response return response 5 2 Delaying Messages Messages can be delayed by using the function delayed_send using poll_atom atom_constant lt atom poll gt behavior poller event_based_actorx self using std chrono seconds self gt delayed_send self seconds 1 poll_atom value return poll_atom poll a resource schedule next polling self gt delayed_send self seconds 1 poll_atom value 12 SENDING MESSAGES 5 3 Forwarding Messages in Untyped Actors The member function forward_to forwards the last dequeued message to an other actor For warding a synchronous message will also transfer responsibility for the request i e the receiver of the forwarded message can reply as usual and the original sender of the message will receive the response The following diagram illustrates forwarding of a synchronous message from actor B to actor C A B sync_send gt forward_to gt x N compute result lr lt reply X handle response Kasi X The forwarding is completely transparent to actor C since it will see actor A as sender of the message However actor A will see actor C as sender of the response message instead
43. pawn tester spawn_typed typed_calculator await_all_actors_done test class based impl spawn tester spawn_typed lt typed_calculator_class gt await_all_actors_done done shutdown return 0 41 MESSAGES 18 Messages Messages in CAF are type erased copy on write tuples The actual message type itself is usu ally hidden as actors use pattern matching to decompose messages automatically However the classes message and message_builder allow more advanced usage scenarios than only sending data from one actor to another 18 1 Class message Member functions Observers bool empty Returns whether this message is empty size_t size Returns the size of this message const voidx at size_t p Returns a const pointer to the element at position p E late lt cl T gt i EA eee Returns a const ref to the element at position p const T get_as size_t p E late lt el T gt ba SAP oo nen i Returns whether the element at position p has type T bool match_element size_t p template lt class Ts gt Returns whether this message has the types Ts bool match_elements message drop size_t n Creates a new message with all but the first n values message drop_right size_t n Creates a new message with all but the last n values message take size_t n Creates a new message fr
44. r This limitation is due to the fact that the address does not contain any type information about the actor Hence it would not be safe to send it any message because the actor might use a strictly typed messaging interface not accepting the given message INTRODUCTION 1 2 2 Actor Handle An actor handle contains the address of an actor along with its type information In order to send an actor a message one needs to have a handle to it the address alone is not sufficient The distinction between handles and addresses which is unique to CAF when comparing it to other actor systems is a consequence of the design decision to support both untyped and typed actors 1 2 3 Untyped Actors An untyped actor does not constrain the type of messages it receives e a handle to an untyped actor accepts any kind of message That does of course not mean that untyped actors must handle all possible types of messages Choosing typed vs untyped actors is mostly a matter of taste Untyped actors allow developers to build prototypes faster while typed actors allow the compiler to fetch more errors at compile time 1 2 4 Typed Actor A typed actor defines its messaging interface i e both input and output types in its type This allows the compiler to check message types statically 1 25 Spawning Spawning an actor means to create and run a new actor 1 2 6 Monitoring A monitored actor sends a down message to all act
45. reason as_string uint32_t normal 1 Actor finished execution without error unhandled_exception 2 Actor was killed due to an unhandled exception Actor was killed due to an unexpected syn unhandled_sync_failure 4 chronous response message Actor was killed because no timeout handler unhandled_sync_timeout 5 i was set and a synchronous message timed out Indicates that an actor has been exited and its unknown 6 state is no longer known Indicates that an actor pool unexpectedly ran out out_of_workers 7 of workers user_shutdown 16 Actor was killed by a user generated event acl 17 Unconditionally kills actors when using in an L A g exit_msg even when trapping exits _ Indicates that a remote actor became unreach remote_link_unreachable 257 able e g due to connection error user defined 65536 Minimum value for user defined exit codes 8 4 Attach Cleanup Code to an Actor Actors can attach cleanup code to other actors This code is executed immediately if the actor has already exited using done_atom atom_constant lt atom done gt behavior supervisor event_based_actorx self actor worker actor observer self monitor spawned actor worker gt attach_functor observer std uint32_t reason this callback is invoked from worker anon_send observer done_atom value wait until worker exited return done_atom worker terminat
46. roup communication Actors can join and leave groups and send messages to groups std string group_module std string group_id auto grp group get group_module group_id self gt join grp self gt send grp test self gt leave grp 13 1 Anonymous Groups Groups created on the fly with group anonymous can be used to coordinate a set of work ers Each call to group anonymous returns a new unique group instance 13 2 Local Groups The local group module creates groups for in process communication For example a group for GUI related events could be identified by group get local GUI events The group ID GUI events uniquely identifies a singleton group instance of the module local 13 3 Remote Groups To deploy groups in a network one host can act as group server by publishing its local groups at any given port void publish_local_groups std uint16_t port const char addr By calling group get remote lt group gt lt host gt lt port gt other hosts are now able to connect to a remotely running group Please note that the group communication is no longer available once the server disconnects This implementation uses N times unicast under neath It is worth mentioning that user implemented groups can be build on top of IP multicast or overlay technologies such as Scribe to achieve better performance or reliability 30 GROUP COMMU
47. rward request to idle worker self gt forward_to worker await next idle message self gt unbecome r idle_atom return skip_message others gt gt die y Fy request_atom return skip_message others gt gt die y 18 SYNCHRONOUS COMMUNICATION 7 Synchronous Communication CAF supports both asynchronous and synchronous communication The latter is provided by the member function sync_send template lt typename Args gt __unspecified__ sync_send actor whom Args amp amp what A synchronous message is sent to the receiving actor s mailbox like any other asynchronous message Only the response message is treated separately 7 1 Additional Error Messages struct sync_exited_msg actor_addr source uint32_t reason When using synchronous messaging CAF s runtime will send a sync_exited_msg message if the receiver is not alive This is in addition to exit and down messages caused by linking or monitoring 7 2 Receive Response Messages When sending a synchronous message the response handler can be passed by either using then event based actors or await blocking actors void foo event_based_actorx self actor testee test replies with a string to get self gt sync_send testee get_atom value then const std string amp str handle str after std chrono seconds 30 gt gt handle error
48. s and deprecates all _send_tuple versions simply use the function without _tuple suffix local_actor on_exit once again became virtual In case you were using the old cppa options_description API you can migrate to the new API based on extract cf 18 4 Most importantly version 0 13 slightly changes last_dequeued and last_sender Both func tions will now cause undefined behavior dereferencing a nul1pt r instead of returning dummy values when accessed from outside a callback or after forwarding the current message Besides these function names were not a good choice in the first place since last implies accessing data received in the past As a result both functions are now deprecated Their replacements are named current_message and current_sender cf Section 4 2 20 3 6 0 13 0 14 The function timed_sync_send has been removed It offered an alternative way of defining message handlers which is inconsistent with the rest of the API The policy classes broadcast random and round_robinin actor_pool were removed and replaced by factory functions using the same name 53
49. s discard_behavior that causes an actor to override its current behavior The policy flag must be the first argument of become Note the message handling in CAF is consistent among all actor implementations unmatched messages are never implicitly discarded if no suitable handler was found Hence the order of arrival is not important in the example above This is unlike other event based implementations of the actor model such as Akka for instance 16 RECEIVING MESSAGES 6 3 Timeouts A behavior set by become is invoked whenever a new message arrives If no message ever arrives the actor would wait forever This might be desirable if the actor only provides a service and should not do anything else But often we need to be able to recover if an expected message does not arrive within a certain time period The following examples illustrates the usage of after to define a timeout behavior eager_actor event_based_actorx self return Gne a LP oe BP by I fleet i 4 Le vee l Fy others gt gt x after std chrono seconds 10 gt gt aout self lt lt received nothing within 10 seconds lt lt endl Callbacks given as timeout handler must have zero arguments Any number of patterns can pre cede the timeout definition but after must always be the final statement Using a zero duration timeout causes the actor to scan its mailbox once and then invoke the timeout immediately if n
50. t or three ints Any other message is not matched and will remain in the mailbox until it is consumed eventually This caching mechanism allows actors to ignore messages until a state change replaces its message handler However this can lead to a memory leak if an actor receives messages it handles in no state To allow actors to specify a default message handlers for otherwise unmatched messages CAF provides others behavior bhvr2 int i ant a fle at f Er int a int b int c x x others gt gt x Please note the change in syntax for the default case The lambda expression passed to the constructor of behavior is prefixed by a match expression and the operator gt gt 3 2 Atoms Assume an actor provides a mathematical service for integers It takes two arguments performs a predefined operation and returns the result It cannot determine an operation such as multiply or add by receiving two operands Thus the operation must be encoded into the message The Erlang programming language introduced an approach to use non numerical constants so called atoms which have an unambiguous special purpose type and do not have the runtime overhead of string constants Atoms are mapped to integer values at compile time in CAF This mapping is guaranteed to be collision free and invertible but limits atom literals to ten characters and prohibits special characters Lega
51. t return a value The types for the pattern are deduced from the functor s signature If the functor returns an option lt T gt then T is deduced 3 6 Dynamically Building Messages Usually messages are created implicitly when sending messages but can also be created explicitly using make_message In both cases types and number of elements are known at compile time To allow for fully dynamic message generation CAF also offers a third option to create messages by using a message_builder message_builder mb prefix message with some atom mb append strings_atom value fill message with some strings std vector lt std string gt strings x x for autos str strings mb append str create the messag message msg mb to_message ACTORS 4 Actors CAF provides several actor implementations each covering a particular use case The class local_actor is the base class for all implementations except for remote proxy actors Hence local_actor provides a common interface for actor operations like trapping exit messages or finishing execution The default actor implementation in CAF is event based Event based actors have a very small memory footprint and are thus very lightweight and scalable Context switching actors are used for actors that make use of the blocking API see Section 16 but do not need to run in a separate thread Context switching and event based actors are scheduled cooperativ
52. t_sender now returns the address of the sender This means that previously valid code such as send last_sender will cause a compiler error However the recommended way of replying to messages is to return the result from the message handler The API for typed actors is now similar to the API for untyped actors The APIs of typed and untyped actors have been harmonized Typed actors can now be published in the network and also use all operations untyped actors can 50 APPENDIX 20 3 2 0 9 gt 0 10 Libcppa gt CAF The first release under the new name CAF is an overhaul of the entire library Some classes have been renamed or relocated others have been removed The purpose of this refactoring was to make the library easier to grasp and to make its API more consistent All classes now live in the namespace caf and all headers have the top level folder caf instead of cppa For example include cppa actor hpp becomes include caf actor hpp Further the convenience header to get all parts of the user API is now caf all hpp The networking has been separated from the core library To get the networking components simply include caf io all hpp and use the namespace caf io g caf 10 remote_actor Version 0 10 still includes the header cppa cppa hpp to make the transition process for users easier and to not break existing code right away The header defines the namespace cppa as an alias for caf Furt
53. to group g void leave const group g Unsubscribes group g void on_sync_failure auto fun Sets a handler i e a functor taking no argu ments for unexpected synchronous response mes sages default action is to kill the actor for reason unhandled_sync_failure void monitor actor whom Unidirectionally monitors whom see Section 8 2 void demonitor actor whom Removes a monitor from whom bool has_sync_failure_handler Checks whether this actor has a user defined sync failure handler template lt class F gt void set_exception_handler F f Sets a custom handler for uncaught exceptions void on_exit Can be overridden to add cleanup code that runs after an actor finished execution e g to break cycles 11 SENDING MESSAGES 5 Sending Messages template lt typename Args gt void send actor whom Args amp amp what Messages can be sent by using the member function send The variadic template parameter pack what is converted to a message and then enqueued to the mailbox of whom void some_fun event_based_actorx self actor other spawn self gt send other 1 2 3 sending a message directly is also ok auto msg make_message 1 2 3 self gt send other msg 5 1 Replying to Messages The return value of a message handler is used as response message Actors can also use the result of a sync_send to answer to a request as shown bel
54. tors output often appears interleaved Moreover using cout from multiple actors and thus from multiple threads in parallel should be avoided regardless since the standard does not guarantee a thread safe implementation By replacing std cout with caf aout actors can achieve a concurrency safe text output The header caf all hpp also defines overloads for std endl and std flush for aout but does not support the full range of ostream operations yet Each write operation to aout sends a message to a hidden actor keep in mind sending messages from actor constructors is not safe This actor only prints lines unless output is forced using flush The example below illustrates printing of lines of text from multiple actors in random order include lt chrono gt include lt cstdlib gt include lt iostream gt include caf all hpp using namespace caf using std endl using done_atom atom_constant lt atom done gt int main std srand std time 0 for int i 1 i lt 50 1 spawn lt blocking_api gt i blocking_actorx self aout self lt lt Hi there This is actor nr lt lt a lt lt Y lt lt endl std chrono milliseconds tout std rand 1000 self gt delayed_send self tout done_atom value self gt receivel 1 self done_atom aout self lt lt Actor nr lt lt ji lt lt says goodbye lt lt endl
55. ver event_based_actorx self spawn functor based actors otherwise auto a0 self gt spawn my_actorl auto al self gt spawn lt linked gt my_actor2 42 hello actor auto a2 self gt spawn lt monitored gt x auto a3 self gt spawn int 42 spawn thread mapped actors auto a4 self gt spawn lt detached gt my_actorl auto a5 self gt spawn lt detached linked gt x x gt auto a6 self gt spawn lt detached gt my_actor2 0 zero spawn class based actors auto a7 self gt spawn lt my_actor3 gt auto a8 self gt spawn lt my_actor4 monitored gt 42 spawn and detach class based actors auto a9 self gt spawn lt my_actor4 detached gt 42 spawn actors that need access to the blocking API auto aa self gt spawn lt blocking_api gt ugly_duckling compiler error my_actor2 captures the implicit self pointer as event_based_actor and thus cannot be spawned using the blocking_api flag auto ab self gt spawn lt blocking_api gt my_actor2 23 MESSAGE PRIORITIES 10 Message Priorities By default all messages have the same priority and actors ignore priority flags Actors that should evaluate priorities must be spawned using the priority_aware flag This flag causes the actor to use a priority aware mailbox implementation It is not possible to change this implementation dynamical
56. way to initialize message handlers and behaviors is to either use the constructor or the member function assign message_handler okl int iy eu Ey float 1 xr x y message_handler ok2 some place later ok2 assign int i L geegeer Fy float e e 19 2 Event Based API e The functions become and handle_response do not block i e always return imme diately Thus one should always capture by value in lambda expressions because all references on the stack will cause undefined behavior if the lambda expression is executed 19 3 Synchronous Messages e A handle returned by sync_send represents exactly one response message Therefore it is not possible to receive more than one response message e The handle returned by sync_send is bound to the calling actor It is not possible to transfer a handle to a response to another actor 46 COMMON PITFALLS 19 4 Sharing e ltis strongly recommended to not share states between actors In particular no actor shall ever access member variables or member functions of another actor Accessing shared memory segments concurrently can cause undefined behavior that is incredibly hard to find and debug However sharing data between actors is fine as long as the data is immutable and its lifetime is guaranteed to outlive all actors The simplest way to meet the lifetime guarantee is by storing the data in smart pointers such as std shared_ptr N

Download Pdf Manuals

image

Related Search

Related Contents

Forethought Manual_Texas_Fall2009  fks - manual fkr500  取扱説明書(PDFファイル)  Nokia N90 importado Agotado Gira la pantalla 90 grados. Te    解説書 Vol.1 - アラクサラネットワークス株式会社  COMS B34 Syllabus - Bakersfield College  Lovibond® Water Testing  取扱説明書  neoplastine® ci plus 10  

Copyright © All rights reserved.
Failed to retrieve file