четверг, 28 мая 2015 г.

[prog] Erlang-style мониторы и супервизоры -- это хорошо, но не ими одними :)

В процессе подготовки презентации об обработки исключений в SObjectizer написал небольшой пример, показывающий, как кооперация перерегистрирует сама себя, если до этого ее грохнули из-за выскочившего наружу исключения.

#include <iostream>

#include <so_5/all.hpp>

using namespace so_5;
using namespace so_5::rt;

using namespace std;

void start_coop( environment_t & env )
{
   env.introduce_coop( [&]( agent_coop_t & coop ) {
      struct raise_exception : public signal_t {};

      // The single agent of the coop.
      // Will throw an exception after one seconds from registration.
      auto agent = coop.define_agent();
      agent.on_start( [agent, &env] {
            send_delayed< raise_exception >(
                  env, agent.direct_mbox(), chrono::seconds(1) );
         } )
         .event< raise_exception >( agent.direct_mbox(), [] {
            throw runtime_error( "Just a test exception" );
         } );

      // Tell to SObjectizer to deregister the coop on exception.
      coop.set_exception_reaction( deregister_coop_on_exception );

      // Add notificator which will initiate reregistration of the coop.
      coop.add_dereg_notificator(
         []( environment_t & env,
            const string & coop_name,
            const coop_dereg_reason_t & why )
         {
            cout << "Deregistered: " << coop_name << ", reason: " << why.reason() << endl;

            if( dereg_reason::unhandled_exception == why.reason() )
               start_coop( env );
         } );
   } );
}

int main()
{
   so_5::launch( []( environment_t & env ) {
         // Register coop the first time.
         start_coop( env );
         // Take some time to the example to work.
         this_thread::sleep_for( chrono::seconds( 5 ) );
         env.stop();
      } );
}

Комментариев нет: