以åã¯ãC ++ã®ã¢ã¯ã¿ãŒãã¬ãŒã ã¯ãŒã¯ãšããŠSObjectizerã«ã€ããŠèª¬æããŸããããå®éã«ã¯ããã¯å®å
šã«çå®ã§ã¯ãããŸããã ããšãã°ãSObjectizerã«ã¯é·ãéã mchains ïŒ CSPã¢ãã«ããã®ãã£ãã«ïŒã®ãããªã¯ãŒã«ãªãã®ããããŸãã Mchain-sã䜿çšãããšãã¯ãŒã¯ãããŒéã§ã®ããŒã¿äº€æãç°¡åãã€èªç¶ã«æŽçã§ããŸãã å¿
ãããå¿
èŠã§ã¯ãªããšãŒãžã§ã³ããäœæããªãã å
æ¥ããã®æ©èœãå©çšããŠããã£ãã«ïŒSObjectizer mchainsïŒãä»ããŠã¹ããªãŒã éã§ããŒã¿ã転éããããšã§ã人çãç°¡çŽ åããæ©äŒãåã³ãããŸããã Goã ãã§ãªããCSPã®äœ¿çšã楜ããããšãã§ããŸãã C ++ã§ã¯ããããå¯èœã§ãã ç«ã®äžã§èª°ãäœãã©ã®ããã«æ°ã«ãããŠãã ããã
ã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ããåæèŠæ±ãè¡ãå¿
èŠãããç¹å®ã®ãµãŒãããŒãã£ã·ã¹ãã ããããŸãã ãªã¯ãšã¹ãã1ã€ã®ã¹ããªãŒã ã§ã¯ãªãè€æ°ã®ã¹ããªãŒã ã«éãããå Žåããã®ã·ã¹ãã ã®åäœã確èªããå¿
èŠããããŸããã ãããè¡ãã«ã¯ãæ¢åã®ã·ã³ã°ã«ã¹ã¬ãããã«ãã¹ã¬ããã¯ã©ã€ã¢ã³ããäœæããå¿
èŠããããŸãããã®ã¯ã©ã€ã¢ã³ãã®äœæ¥ã¹ã¬ããã¯ãç¬èªã®ãªã¯ãšã¹ãã¹ããªãŒã ããµãŒãããŒãã£ã·ã¹ãã ã«çºè¡ããŸãã
å®è¡ãããã¯ãã ã£ããªã¯ãšã¹ãã®å®å
šãªãªã¹ãã¯ãå¥ã®ãã¡ã€ã«ã«ãããŸããã ãã®ããããã®ãã¡ã€ã«ãé çªã«èªã¿åããå¥ã®èŠæ±ãååŸããŠã空ãäœæ¥ã¹ã¬ããã®1ã€ã«æž¡ãå¿
èŠããããŸããã åã¹ã¬ããã¯ãå®äºãããªã¯ãšã¹ãã®æ°ãã«ãŠã³ãããŸããã ãã¹ãŠã®ãªã¯ãšã¹ããæ ¡æ£ããŠåŠçããã®ã«ãããæéãæ±ºå®ããå®äºãããªã¯ãšã¹ãã®æ°ãèšç®ããå¿
èŠããããŸããã
æãããªè§£æ±ºçã¯åçŽãªè§£æ±ºçã§ããã èŠæ±ãã¡ã€ã«ãèªã¿åãã¡ã€ã³ã®äœæ¥ã¹ã¬ããããããŸãã åãªã¯ãšã¹ãã¯ããªã¯ãšã¹ãã®äžè¬çãªãã¥ãŒã«å
¥ããããŸãã äœæ¥ã¹ã¬ããã«ãã£ãŠãªã¯ãšã¹ããè§£æãããå Žæã ããªãã¡ äœæ¥ã¹ã¬ããã¯ãã¥ãŒããæåã®ãªã¯ãšã¹ããååŸããŠå®è¡ããæ¬¡ã«ãã¥ãŒããæ°ããæåã®ãªã¯ãšã¹ããååŸããŸãã ãã¥ãŒã空ã®å Žåãäœæ¥ã¹ã¬ããã¯ãã¥ãŒã«äœããçŸãããŸã§äžæåæ¢ããå¿
èŠããããŸãã ãã£ã±ãã«ãªã£ãŠããå Žåã¯ããã¥ãŒã«ç©ºãé åãçŸãããŸã§ã¡ã€ã³ã¹ã¬ãããäžæããå¿
èŠããããŸãã
SObjectizerã®Mchainã䜿çšãããšãã¹ã¬ããã»ãŒããã¥ãŒãäœæããã«å®è¡ã§ããŸãã
ãã®åé¡ã解決ããã«ã¯ã2ã€ã®mchainãå¿
èŠã§ããã æåã®mchainã¯ãèªã¿åãèŠæ±ãäœæ¥ã¹ã¬ããã«éä¿¡ããããã«äœ¿çšãããŸãã ã¡ã€ã³ã¹ã¬ããã¯ãªã¯ãšã¹ããæžã蟌ã¿ã
ã¯ãŒã«ãŒã¹ã¬ããã¯ãããããªã¯ãšã¹ããèªã¿åããŸãã èŠæ±ãã¡ã€ã«ãå®å
šã«èªã¿åããããšãã¡ã€ã³ã¹ã¬ããã¯ãã®mchainãéããŸãã ãããã£ãŠãã¯ãŒã«ãŒã¹ã¬ãããmchainã«äœãååšãããéããããŠããããšãããããšãããã«äœæ¥ãå®äºããŸãã
2çªç®ã®mchainãå¿
èŠã ã£ãã®ã¯ãäœæ¥ã¹ã¬ããããäœæ¥ãšåŠçãããªã¯ãšã¹ãã®æ°ãä¿èšŒããæ
å ±ãã¡ã€ã³ã¹ã¬ããã«è»¢éã§ããããã«ããããã§ããã ãã®mchainã§ã¯ãã¯ãŒã«ãŒã¹ã¬ããã¯1ã€ã®ã¡ãã»ãŒãžã®ã¿ãæžã蟌ã¿ãŸãã ãããŠãã¡ã€ã³ã¹ã¬ããã¯ãã®mchainããã®ã¿èªã¿åããŸãã
ããŠãããã§ãã¹ãŠãã³ãŒãã§ã©ã®ããã«èŠããããèŠãããšãã§ããŸãã ã³ã¡ã³ããªãã®ã³ãŒã äžåºŠã ãã®æåºããã°ã©ã ã§ããã ãããã£ãŠãå¿
èŠãªèª¬æã¯ã察å¿ããã³ãŒãã®åŸã«ââèšèŒãããŸãã
run_app颿°ããå§ããŸããããããã¯ãããã°ã©ã ãã³ãã³ãã©ã€ã³ãã©ã¡ãŒã¿ãŒãè§£æããçŽåŸã«mainïŒïŒããåŒã³åºãããŸãã
void run_app( const app_args_t & args ) { so_5::wrapped_env_t sobj( []( so_5::environment_t & ) {}, []( so_5::environment_params_t & params ) { params.infrastructure_factory( so_5::env_infrastructures::simple_mtsafe::factory() ); } ); auto tasks_ch = create_mchain( sobj, std::chrono::seconds(5), 50, so_5::mchain_props::memory_usage_t::preallocated, so_5::mchain_props::overflow_reaction_t::abort_app ); auto finish_ack_ch = create_mchain( sobj ); std::vector< std::thread > workers; const auto cleanup = cpp_util_3::at_scope_exit( [&] { so_5::close_drop_content( finish_ack_ch ); so_5::close_drop_content( tasks_ch ); for( auto & t : workers ) t.join(); } ); cpp_util_3::n_times( args.m_threads_count, [&] { workers.emplace_back( [&] { worker_thread( args, tasks_ch, finish_ack_ch ); } ); } ); do_main_work( args, tasks_ch, finish_ack_ch ); }
ããã§ã¯ããŸããmObjectãå±ããSObjectizer Environmentã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã SOEnvironmentããªããšãmchainãäœæã§ããªããããSOEnvironmentãäœæããå¿
èŠããããŸãã
ãã ããSOEnvironmentãè€æ°ã®ç¬èªã®è£å©ã¹ã¬ãããäœæããããšã匷å¶ããã广çãªç®¡çã®ããã«ãã¢ããªã±ãŒã·ã§ã³å
ã«ãšãŒãžã§ã³ãã®ã¯ã©ãŠããäœæããããã«èšèšãããæ¬æ ŒçãªSOEnvironmentã¯å¿
èŠãããŸããã ãããã£ãŠãSOEnvironmentã®ãã©ã¡ãŒã¿ãŒã§ã¯ã ç¹å¥ãªã·ã³ã°ã«ã¹ã¬ããããŒãžã§ã³ã®SObjectizerã䜿çšããããã«èŠæ±ããŸãã ãã®å Žåãwrapped_env_tã¯1ã€ã®è£å©ã¹ã¬ãããäœæãããã®äžã§so_5 :: launchïŒïŒãåŒã³åºãããŸãã ãã以äžã®SObjectizerã¯äœãããŸããã ã¯ãããã®è£å©ã¹ã¬ããã¯ãrun_appããæ»ããŸã§so_5 :: launchïŒïŒã§ã¹ãªãŒãããŸãã
次ã«ããªã¯ãšã¹ããäœæ¥ã¹ã¬ããã«åæ£ããããã«mchainãå¿
èŠã§ãã ãããtasks_chã§ãã ããããããã¯åçŽãªmchainã§ã¯ãããŸããã ãŸãã容éãå¶éãããmchainã§ãã ãã£ã±ãã«ãªã£ãmchainã«å¥ã®ã¡ãã»ãŒãžã远å ããããšãããšãçŸåšã®ã¹ã¬ããããããã¯ãããŸãã ãã ããæ°žä¹
ã«ãããã¯ããã®ã§ã¯ãªãã5ç§éã ããããã¯ããŸãã 5ç§åŸã§ãmchainã«ç©ºãé åããªãå Žåãstd :: abortïŒïŒãåŒã³åºãããšã§ã¢ããªã±ãŒã·ã§ã³å
šäœãäžæãããŸãã ãã®å Žåãæ£åœåãããŸãã éåžžã®ç¶æ
ã§ã¯ã5ç§ã¯èšããŸã§ããªããåäœäžã®ã¹ã¬ããã®1ã€ãæ°ããªç§ä»¥äžã¹ãªãŒãç¶æ
ã«ãªãããšã¯ãããŸããã ãããã£ãŠã5ç§ä»¥å
ã«tasks_chã«ç©ºãé åããªãå Žåã¯ãééããçºçããŠããã®ã§ãstd :: abortïŒïŒãåŒã³åºãå¿
èŠããããŸãã ããã«ãtasks_chã®ãµã€ãºã¯ãããããæ±ºããããŠãããããmchainã®ã¡ãã»ãŒãžãã¥ãŒå
šäœã«å¿
èŠãªã¡ã¢ãªãããã«å²ãåœãŠãããã«æç€ºããŸãã
ã¯ãŒã«ãŒã¹ã¬ãããfinish_ackã¡ãã»ãŒãžãéä¿¡ãã2çªç®ã®mchainã§ã¯ããã¹ãŠãã¯ããã«åçŽã§ãã ãããã£ãŠãfinish_ack_chã¯ãããã©ã«ãã®ãã©ã¡ãŒã¿ãŒïŒéä¿¡æäœããããã¯ããªãç¡æ¬¡å
mchainïŒã䜿çšããŠcreate_mchainãåŒã³åºãã ãã§äœæãããŸãã
次ã«ãNåã®äœæ¥ã¹ã¬ãããéå§ããããããã¯ãŒã«ãŒãã¯ãã«ã«ä¿åããå¿
èŠããããŸãã ããããããã§ã¯ããã»ã©åçŽã§ã¯ãããŸããã æ¬¡ã®äœæ¥ã¹ã¬ãããäœæãããšãã«äŸå€ãååŸã§ããŸãã ãã®å Žåããã§ã«äœæãããŠããã¹ã¬ãããéåžžå®äºãããšäŸ¿å©ã§ãã
以åã«å®è¡ããæäœãããŒã«ããã¯ããŠç掻ãç°¡çŽ åããããã«ãDã¹ã³ãŒãsc_exitã®ã¢ããã°ã䜿çšãããŸãïŒBOOST_SCOPE_EXITã®ã¢ããã°ããGã»ã¯ã·ã§ã³ã®å»¶æã®ãããããããã§ã¯èª°ã«ãè¿ãïŒã ã¯ãªãŒã³ã¢ãã倿°ã¯ãåºæ¬çã«å
éšã«ã©ã ããæã€ãªããžã§ã¯ãã§ãã ãã®ã©ã ãã¯ãã¯ãªãŒã³ã¢ãã倿°ãåŒã³åºããããšãã«åŒã³åºãããŸãã å°ããªcpp_utilãã«ããŒã©ã€ãã©ãªã䜿çšããã¯ãªãŒã³ã¢ããã«ãã£ãŠäœæãããŸãã ã¯ãªãŒã³ã¢ããã«é¢ããå¥ã®èª¬æïŒã¯ãªãŒãã³ã°æã«æåã«è¡ãå¿
èŠãããã®ã¯ãmchainsãéããããšã§ãã äœæ¥ã¹ã¬ããã®ããããããã§ã«éå§ãããtasks_chããã®åä¿¡åŒã³åºãã§ã¹ãªãŒãç¶æ
ã«ãªã£ãå Žåãã¯ãªãŒã³ã¢ããã§tasks_chãéãããšãããã«ãã®ã¹ã¬ãããèµ·åããäœæ¥ãå®äºããããšãã§ããŸãã
ããã§ã¯ãäœæ¥ã¹ã¬ãããäœæããŠdo_main_workãåŒã³åºããŸãã do_main_workã®å
éšã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã¹ã¬ããã®ã¡ã€ã³äœæ¥ãå®è¡ãããŸãããªã¯ãšã¹ããå«ããã¡ã€ã«ã®èªã¿åããäœæ¥ã¹ã¬ãããžã®ãªã¯ãšã¹ãã®éä¿¡ãçµæã®åéã§ãã æ¬¡ã«ãdo_main_workã®ç°¡æããŒãžã§ã³ãã©ã®ããã«èŠãããã瀺ããŸãããã®ããŒãžã§ã³ãããã€ããŒãªè©³çްãåé€ãããŸããã
void do_main_work( const app_args_t & args, so_5::mchain_t tasks_ch, so_5::mchain_t finish_ack_ch ) { data_file_handler_t file{ args.m_data_file, args.m_force_keep_alive }; const auto started_at = hires_clock::now(); while( !file.is_eof() ) { auto request = file.get_next_request(); if( !request ) break; so_5::send< std::string >( tasks_ch, *request ); } so_5::close_retain_content( tasks_ch ); unsigned long long total_requests{}; so_5::receive( from(finish_ack_ch).handle_n( args.m_threads_count ), [&]( const finish_ack_t & what ) { total_requests += what.m_requests; } ); const auto total_time = hires_clock::now() - started_at; if( total_requests ) { ...
ããã§æãè峿·±ããã®ã¯ãã¹ãŠ2ã€ã®å Žæã«éããããŠããŸãã
ãŸãããã°ããã®éã ããã§ã¯ããã¡ã€ã«ããã®ãªã¯ãšã¹ããé çªã«èªã¿èŸŒãŸããsendãåŒã³åºãããšã§ã¯ãŒã¯ã¹ã¬ããã«æž¡ãããŸãã tasks_chããã£ã±ãã®ãšãã«sendãåŒã³åºããããšãã¡ã€ã³ã¹ã¬ããã¯äžæãããŸãïŒãã ãã5ç§ä»¥å
ïŒã
第äºã«ããªã¯ãšã¹ããã¡ã€ã«å
šäœãèªã¿èŸŒãŸãããããã¹ãŠã®äœæ¥ã¹ã¬ããããã®å¿çãåŸ
ã€å¿
èŠããããŸãã ãããè¡ãã«ã¯ãæåã«tasks_chãéããŠãäœæ¥äžã®ã¹ã¬ãããäœæ¥ãå®äºããæãæ¥ãããšãçè§£ããŸãã ãã ããæ¢ã«ãã¥ãŒã«ããããŸã åŠçãããŠããªãèŠæ±ã倱ãããããã«ããããéããå¿
èŠããããŸãã ãããã£ãŠãclose_retain_contentãåŒã³åºãããŸãïŒãã ããrun_appã®ã¯ãªãŒã³ã¢ããã¢ã¯ã·ã§ã³ã§ã¯ãclose_drop_contentã䜿çšãããŸãããããã¯ãéããããŠãããã£ãã«ã«äœãä¿åããå¿
èŠããªãããã§ãïŒã
tasks_chãéããåŸãNåã®äœæ¥ã¹ã¬ããããã®å¿çãåŸ
ã€å¿
èŠããããŸãã æ£ç¢ºã«Nåã®åçãæåŸ
ãããããšã¯ã1ã€ã®éæ³ã®è¡ã«èšé²ãããŸãã
so_5::receive( from(finish_ack_ch).handle_n( args.m_threads_count ),
圌女ã¯ãæåéãæ¬¡ã®ããã«èšã£ãŠããŸããthreads_countåã®ã¡ãã»ãŒãžãèªã¿åãããŠåŠçããããŸã§ãfinish_ack_chãã£ãã«ããèªã¿åããŸãã
ããŠãå³ã宿ãããã«ã¯ãäœæ¥ã¹ã¬ããã®ã³ãŒããã©ã®ããã«èŠãããã瀺ãå¿
èŠããããŸãã ããã¯éåžžã«ç°¡åã§ãïŒ
void worker_thread( const app_args_t & args, so_5::mchain_t tasks_ch, so_5::mchain_t finish_ack_ch ) { io_performer_t io_performer{ args.m_srv, args.m_port }; unsigned long long total_requests{}; so_5::receive( from(tasks_ch), [&]( const std::string & request ) { io_performer.request_response( request ); ++total_requests; } ); so_5::send< finish_ack_t >( finish_ack_ch, total_requests ); }
ã¹ã¬ããã¯ãtasks_chãã£ãã«ããreceiveå
ã§ãã³ã°ããŸãã åä¿¡ããã®æ»ãã¯ãtasks_chãéãããããšãã«çºçããŸãã tasks_chã空ã®å Žåãreceiveã¯ãŸã§ã¹ãªãŒãããŸã
äœãããã£ãã«ã«å
¥ããŸã§ïŒãŸãã¯ãã£ãã«ãéãããããŸã§ïŒã ãããŠãåä¿¡ããã®æ»ããçºçãããšãäœæ¥ã¹ã¬ããã¯åã«finish_ackã¡ãã»ãŒãžãfinish_ack_chã«éä¿¡ããŠçµäºããŸãã
å®éãããããã¹ãŠã§ãã
ãããŒéã®ãã«ãã¹ã¬ããåãšæ
å ±äº€æã«åé¡ã¯ãªãã£ããšèšããããåŸãŸããã æåéããæåã«èµ·åããŠåäœããŸããã io_performer_t :: request_responseå®è£
å
ã§åé¡ãçºçããŸãããã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®å¯Ÿè©±ã®å®è£
ã®ãšã©ãŒãåå ã§ãçŸåšã®ã¹ã¬ãããäžæãããŸããã ãããŠãtasks_chå
šäœãžã®æžã蟌ã¿ãåŸ
æ©ããæéã®5ç§ã®å¶éã圹ç«ã¡ãŸãããã¹ã¬ããããã³ã°ãå§ãããšããã¿ã€ã ã¢ãŠããæ©èœãããã«ãã¹ã¬ããã¯ã©ã€ã¢ã³ããã¯ã©ãã·ã¥ããŸããã ãã°ãããã«request_responseã«ãã°ãããããšãããã«æããã«ãªããŸããã tasks_chããã®éåžžã®èªã¿åãã忢ã§ããã®ã¯ãããã«ã¶ãäžãã£ãŠããã ãã§ãã
çµè«ãšããŠãã¢ã¯ã¿ãŒã®ã¢ãã«ãšã€ã³ã¿ã©ã¯ãã£ãã·ãŒã±ã³ã·ã£ã«ããã»ã¹ã®ã¢ãã«ïŒå¥åCSPïŒã®äž¡æ¹ãçŽ æŽããããã®ã§ãããšèšããããšæããŸãã 1ã€ã¯ããŸãæ©èœãã2ã€ç®ã¯ã©ããã§æ©èœããŸãã SObjectizerã§ã¯ãäž¡æ¹ã䜿çšã§ããŸãã ãããŠãäžåºŠã«ãã¹ãŠãæã«ã¯ãããæã
å¿
èŠã§ãã