CAF 開始與 Actor 溝通

Actor model 基本上是 actor 與 actor 之間的 messages 傳遞。你要開始 trigger actor 的動作,一定要先有一個進入點,也就是創造一個 entry actor。

最基本的方法,就是直接使用 function 來實作你的 entry actor。並在 function block 填上你的 start-up code。之後在你的 main thread,使用 spawn function 產生 actor 後。再用 await_all_actors_done() 來 join 完成的 actor。

event based actor
void starter(caf::event_based_actor* self, ... )
{
    self->sync_send(...).then(...); // 使用 sync_send + then 來接收 response
    self->send(...);                // 使用 send 來送達一個無須 reply 的 message 
}
int main()
{
    caf::spawn(starter, ...);       // spawn 下達後,其實會是 separate 另一個 thread
    caf::await_all_actors_done();   // 等待 thread join
    caf::shutdown();
}
blocking based actor
void starter(caf::blocking_actor* self, ... )
{
    self->sync_send(...).await(...); // blocking_actor 需要用 await 來強迫 blocking 
                                     // 去接收 response
    self->send(...);                 // 一樣是使用 send 來送達一個無須 reply 的 message 
}
int main()
{
    caf::spawn<blocking_api>(starter, ...); // 對於 blocking_actor 的 spawn,一定要加上
                                            // blocking_api 的 template parameter
                                            // 否則會 compile error
    caf::await_all_actors_done();
    caf::shutdown();
}

CAF 有提供一個 blocking actor 的方便 wrapper。你不須要另外開一個 function 跟 thread 去取得你的 entry actorcaf::scoped_actor 可以直接像上面兩例的實作 function 中的 self 參數一樣,來做 send/sync_send + await 的訊息送達操作。本質上,他就是 override 了 blocking_actor* operator-> (),回傳他內部的 actor。

wrapped blocking based actor as scoped_actor
int main()
{
    caf::scoped_actor sa;
    sa->sync_send(...).await(...);     // 直接在 main funtion block 內作 message sending 的操作
    sa->await_all_other_actors_done(); // 多了一個 `other_`
    caf::shutdown();
}
comments powered by Disqus