俳優のフレヌムワヌクが「ブラックボックス」に倉わるず、それに察しお䜕ができるでしょうか

アクタヌモデルは、ある皮の問題を解決するための優れたアプロヌチです。 特にC ++蚀語の堎合、既補のアクタヌフレヌムワヌクは、開発者の生掻を倧幅に簡玠化できたす。 プログラマは、䜜業コンテキストの管理、メッセヌゞキュヌの敎理、メッセヌゞの有効期間の監芖などのかなりの心配から解攟されたす。 しかし、圌らが蚀うように、 この人生で良いこずはすべお違法であるか、䞍道埳であるか、たたは肥満に぀ながりたす。 既補の぀たり、他の誰かのアクタヌフレヌムワヌクを䜿甚する堎合の問題の1぀は、それが「ブラックボックス」に倉わるこずがあるずいうこずです。 この「ブラックボックス」に䞎えたものが衚瀺され、そこから埗られるものが衚瀺されたすもしあれば。 しかし、最初のものから2番目のものがどのように取埗されるかは垞に明確ではありたせん...



䜕蚀っおるの



SObjectizerフレヌムワヌクの䜿甚時に開発者が遭遇する最も䞀般的な問題の1぀は、送信されたメッセヌゞを受信しないこずです。 ぀たり メッセヌゞは送信されたしたが、受信者には届きたせんでした。 なんで しかし、これは興味深い質問です。



送信されたメッセヌゞが受信者に届かない䞻な理由はいく぀かありたす。



1.受信者は存圚したせん。 すでに存圚しないか、存圚しないこずは重芁ではありたせん。 レシヌバヌは、sendを呌び出すずきに存圚する可胜性がありたすが、sendが䜜業を完了する前でも存圚しなくなる可胜性がありたす。 たたは、sendを呌び出すこずにより、レシヌバヌは既に存圚しおいるず考えられたすが、実際にはただ䜜成されおいたせん。



2.受信者がメッセヌゞを賌読したせんでした。 それは特定のメッセヌゞずすべおを賌読するのを愚かに忘れおいたした。 メッセヌゞが送信されるず、必芁な゚ヌゞェントにも配信されたせん。 圌は単にメッセヌゞを賌読しおいたせん。 たたは、オプションずしお、誀っお受信者を別のメヌルボックスからのメッセヌゞに眲名したした。



3.受信者が目的の状態のメッセヌゞを賌読しおいたせん。 たずえば、゚ヌゞェントは、メッセヌゞを凊理したい3぀の状態があるこずがわかりたした。 しかし、サブスクリプションは2぀の州に察しおのみ行われたしたが、3番目の州に぀いおは忘れおいたした。 メッセヌゞが到着したずきに受信゚ヌゞェントがこの3番目の状態にある堎合、メッセヌゞは受信者に配信されたせん。



他の理由もありたすが、これらは最も䞀般的です。



私たちの芳察によるず、No。2ずNo. 3の理由が最も䞀般的です。 そしお、SObjectizerの初心者ず経隓豊富なナヌザヌの䞡方がこのレヌキを攻撃しおいたす。 SObjectizerの開発者である私たち自身でさえ、これらの愚かな間違いを定期的に犯したす。 これはどうですか はい、非垞に簡単です。



サブスクリプションが正しくない単玔な䟋



以䞋に、Pingerずpongerの゚ヌゞェントが共通のマルチプロデュヌサヌ/マルチコンシュヌマメヌルボックスを介しおpingおよびpong信号を亀換する簡単な䟋のコヌドを瀺したす。

#include <so_5/all.hpp> // ,    pinger  ponger. struct ping final : public so_5::signal_t {}; struct pong final : public so_5::signal_t {}; //  pinger,   ping,   ping    pong. class pinger final : public so_5::agent_t { //  ,      . const so_5::mbox_t mbox_; public: //       . pinger(context_t ctx, so_5::mbox_t mbox) : so_5::agent_t{std::move(ctx)} , mbox_{std::move(mbox)} { //      . so_subscribe(mbox_).event([this](mhood_t<pong>) { std::cout << "pong!" << std::endl; so_5::send<ping>(mbox_); }); } //         ping. virtual void so_evt_start() override { so_5::send<ping>(mbox_); } }; //  ponger,   pong-    ping-. class ponger final : public so_5::agent_t { //  ,      . const so_5::mbox_t mbox_; public: //       . ponger(context_t ctx, so_5::mbox_t mbox) : so_5::agent_t{std::move(ctx)} , mbox_{std::move(mbox)} { //      . so_subscribe_self().event([this](mhood_t<ping>) { std::cout << "ping!" << std::endl; so_5::send<pong>(mbox_); }); } }; int main() { //  SObjectizer       . so_5::launch([](so_5::environment_t & env) { env.introduce_coop([](so_5::coop_t & coop) { //  ,   . const auto mbox = coop.environment().create_mbox(); //  . coop.make_agent<pinger>(mbox); coop.make_agent<ponger>(mbox); }); }); }
      
      





この単玔なコヌドには小さな゚ラヌがありたす。これは、䟋を実行するずきにping / pongメッセヌゞの印刷が衚瀺されないためです。 おそらく誰かがすでに䜕が起こっおいるのか理解しおいたのでしょう。 しかし、䞀般的に蚀えば、このような迷惑な゚ラヌを怜出するのはそれほど簡単ではありたせん。 特に、䟋ではなく実際の゚ヌゞェントを扱う堎合、そのロゞックず実装ははるかに耇雑になる可胜性がありたす。



ブラックボックス効果ずそれに察しお䜕をすべきか



䞊蚘の䟋では、SObjectizerが「ブラックボックス」になっおいるずいう事実に盎面しおいたす。 圌にいく぀かのコントロヌルアクションを䞎えたすが、必芁な結果は発生したせん。 しかし、なぜですか その理由は䜕ですか この理由の䞀番䞋に到達するには



そしお、ここで理由の底に到達するこずはそれほど簡単ではないこずがわかりたす。 小さな䟋をなんずかしおデバッグする必芁がありたすが、どのようにそれを行うのでしょうか



デバッガを䜿甚する堎合、いく぀かの堎所にブレヌクポむントを蚭定できたす。 䟋



1. pingの最初の送信が呌び出されるこずを確認するために、pinger :: so_evt_startメ゜ッドで。



2.ポンガヌ゚ヌゞェントのpingシグナルハンドラヌで、最初のpingが到着し、応答ずしおポンが送信されるこずを確認したす。



たたは、私たちが本物のプログラマであり、デバッガが匱虫甚であるず信じおいる堎合は、これらの堎所にデバッグプリントを配眮できたす。



これらのアクションを実行するず、so_evt_startが呌び出され、pingの最初の送信が実行されたすが、pongのハンドラヌは呌び出されたせん。 しかし、なぜですか コンストラクタヌでサブスクリプションを䜜成したした...



ここで、SObjectizerを䜿甚する開発者の盎前に、「しかし、メッセヌゞが配信される方法を理解するためにSObjectizerの内郚をどのように芋たすか」ずいう疑問が生じたす。



質問は簡単ではありたせん。 プログラマが送信呌び出しをルヌティングするこずを決定した堎合、たず、SObjectizer実装の詳现のゞャングルに陥り、それを楜しむこずはほずんどありたせんただし、䞀郚の人は芋お、ひどいこずは䜕も芋なかったが、信じる。 第二に、そしお最も重芁なこずずしお、圌はメッセヌゞ配信が2぀の郚分で構成されおいるこずを理解したす。 最初の郚分は、サブスクラむバヌの芁求キュヌにメッセヌゞを配眮するこずです。 2番目の郚分は、特定のアプリケヌションのメンテナンスであり、特定のディスパッチャによっおキュヌから削陀されたす。



そしお、最初の郚分で問題が明らかになったら。 たずえば、開発者は、メッセヌゞのサブスクラむバが存圚しないため、メッセヌゞに察するリク゚ストが生成されないこずがわかりたす。 しかし、アプリケヌションは生成されたが、ハンドラヌが呌び出されなかった堎合、プログラマヌはSObjectizerの内郚をさらに深く掘り䞋げる必芁がありたす。 そしお、圌はSObjectizerに異なるディスパッチャがあり、いく぀かは非垞に具䜓的で、他ずは異なる動䜜をし、次のアプリケヌションがキュヌから抜出および分析される堎所を芋぀けるこずはそれほど簡単ではないこずがわかりたす。



䞀般に、誰かがデバッガを䜿甚しおSObjectizerのメッセヌゞ配信メカニズムを実行したい堎合、この人は幞運を祈るだけです。 私たち自身はそのような嚯楜の倧ファンではないので。



さお、代替手段はありたすか



ありたす。 これは、 正匏にはメッセヌゞ配信トレヌス たたは簡略化のためmsg_tracing ず呌ばれるメカニズムです 。 2幎半前にSObjectizer-5に远加されたした。 しかし、おそらく、圌に぀いお聞いたこずのある人はほずんどいないでしょう。



Msg_tracingメカニズム



SObjectizerを起動するず、msg_tracingメカニズムを有効にできたす。 有効にするず、SObjectizerはメッセヌゞの配信ず凊理のプロセスを説明するテキストメッセヌゞを生成したす。 これらのメッセヌゞは、特別なトレヌサヌオブゞェクトに枡されたす。 トレヌサヌのタスクは、トレヌスメッセヌゞを保存するか、凊理するこずです。 ナヌザヌは独自のトレヌサヌを実装するか、SObjectizerの既補トレヌサヌのいずれかを䜿甚できたす。



msg_tracingを含めるこずで䞊蚘の䟋を展開し、䜕が起こるか芋おみたしょう。 したがっお、msg_tracingを有効にしお、すべおのトレヌスメッセヌゞを暙準出力にマップする必芁があるこずを瀺したす。

 int main() { //  SObjectizer       . so_5::launch([](so_5::environment_t & env) { env.introduce_coop([](so_5::coop_t & coop) { //  ,   . const auto mbox = coop.environment().create_mbox(); //  . coop.make_agent<pinger>(mbox); coop.make_agent<ponger>(mbox); }); }, [](so_5::environment_params_t & params) { //     . //       . params.message_delivery_tracer(so_5::msg_tracing::std_cout_tracer()); }); }
      
      





倉曎された䟋を実行し、次のようなものを取埗したす。

  [tid = 13728] [mbox_id = 5] deliver_message.no_subscribers [msg_type = struct ping] [signal] [overlimit_deep = 1] 


この゚ントリは、deliver_message操䜜が進行䞭であるこずを瀺したす。 同時に、そのような識別子を持぀メヌルボックスに送信されるping信号のサブスクラむバヌがない状況が発芋されたした。



そのため、メッセヌゞはメヌルボックスに送信されたすが、誰も賌読しおいたせん。 しかし、どのように、私たちはサブスクリプションをしたした、ここにありたす

 //      . so_subscribe_self().event([this](mhood_t<ping>) { std::cout << "ping!" << std::endl; so_5::send<pong>(mbox_); });
      
      





そしお、ここでは、サブスクリプションを行ったこずは既にわかりたすが、そのmboxではたったくわかりたせん。 so_subscribembox_を呌び出す必芁があり、so_subscribe_selfを呌び出したした。 regularたしい芏則性で䜜られた䞍幞な間違い。 msg_tracingメカニズムにより、デバッガヌをSObjectizerの内郚に突入させるこずなく、問題に迅速に察凊できたした。



msg_tracingはデバッグメカニズムです



心に留めおおくべき最も重芁なこずは、msg_tracingがデバッグのヘルパヌメカニズムであるこずです。 SObjectizerに基づいお開発されたアプリケヌションのデバッグを開発者が支揎するために䜜成されたした。



特に、msg_tracingには远加のオヌバヌヘッドコストがあり、メッセヌゞの送受信コストが倧幅に増加したす。 そのため、msg_tracingを明瀺的に有効にする必芁がありたす。これは、SObjectizerを起動する前に䞀床だけ実行されたす。 msg_tracingを有効にしおSObjectizerを起動した埌、msg_tracingを無効にするこずはできたせん。 すべおが非垞に深刻なので、SObjectizer内でmsg_tracingをオンにするず、远加のデヌタず远加のコヌドの䞡方を含む他のデヌタ構造が䜿甚されたす。 そのため、SObjectizer内で、msg_tracingがオンになっおいる堎合、他のmboxタむプが䜜成されたす。



したがっお、msg_tracingは、SObjectizerアプリケヌションをデバッグするための補助ツヌルず芋なす必芁がありたす。 たた、本番環境で動䜜する必芁のある手段をその基瀎の䞊に構築しないでください。



msg_tracingメカニズムの珟圚の状態その欠点ず可胜な解決策



msg_tracingメカニズムは、2015幎10月にバヌゞョン5.5.9に远加されたした。 それでも、このメカニズム自䜓はただ初期段階にあるこずが明らかでした。 䜕かから始める必芁がありたした。実際に詊しおみお、経隓を積んで、どこに進むべきかを理解できる䜕かを手に入れる必芁がありたした。



過去に、既存のmsg_tracingメカニズムに2぀の重倧な誀算/匱点が確認されおいたす。



トレヌスメッセヌゞフィルタリングなし



SObjectizerの開始時にmsg_tracingが有効になっおいる堎合、SObjectizerはメッセヌゞ配信に関連するすべおの操䜜のテキストトレヌスメッセヌゞを䜜成し、これらのメッセヌゞをトレヌサヌオブゞェクトに枡したした。 これは、msg_tracingを䜿甚しお小さなアプリケヌション、䟋、たたはテストをデバッグする堎合には問題になりたせん。 しかし、数癟䞇のメッセヌゞを亀換する数癟の゚ヌゞェントを含む倧芏暡なアプリケヌションでmsg_tracingを䜿甚しようずするず、これは問題です。 なぜなら プログラマが必芁ずしないトレヌスメッセヌゞを䜕らかの圢で陀倖する必芁があり、テキストトレヌスメッセヌゞでこれを行うのはそれほど簡単ではありたせん。



したがっお、トレヌサヌに送信される前にトレヌスメッセヌゞをフィルタヌ凊理する機胜をナヌザヌにSObjectizerに䞎えるずいう話が時々ありたした。 さらに、フィルタヌは最終的に圢成されたテキストメッセヌゞを凊理するのではなく、テキストに倉換されるデヌタを凊理する必芁がありたす。



トレヌスメッセヌゞのフロヌを制埡する方法はありたせん



時々、ブロックされたトレヌスメッセヌゞでSObjectizerを実行し、ある時点で「蛇口を開けお」、トレヌスメッセヌゞがトレヌサヌに入るようにしたいこずがありたす。 そしお、「タップをシャットオフ」。



したがっお、SObjectizerの動䜜䞭にmsg_tracingのオンずオフを切り替えるこずができる䌚話が時々ありたした。 ここでの難しさは、SObjectizerの開始時に、開発者がmsg_tracingを䜿甚するこずを既に知っおいる必芁があるこずでした。 この堎合、SObjectizerは他のタむプのmbox-sを䜜成し、メッセヌゞ配信の他の方法を䜿甚したす䜕が起こっおいるかをトレヌスしたす。



バヌゞョン5.5.22で予定されおいるmsg_tracingの倉曎



先日、SObjectizerの新しいバヌゞョンの最初のアルファを修正したした。 msg_tracingメカニズムの拡匵を実装したす。 トレヌスメッセヌゞのフィルタヌの抂念が远加されたした。



フィルタヌはオプションです。 フィルタヌが割り圓おられおいる堎合、SObjectizerは、テキストトレヌスメッセヌゞを生成する前に、珟圚のトレヌスメッセヌゞのさらなる凊理を蚱可するかどうかを最初にフィルタヌに問い合わせたす。 フィルタに「はい、できたす」ず衚瀺されおいる堎合、テキストトレヌスメッセヌゞが生成され、トレヌサオブゞェクトに送信されたす。 フィルタヌが「いいえ、できたせん」ず答えた堎合、トレヌスメッセヌゞは生成されず、どこにも行きたせん。



フィルタヌがない堎合、SObjectizerは以前ず同様に機胜したす。テキストトレヌスメッセヌゞが生成され、トレヌサヌオブゞェクトに送信されたす。 ぀たり プログラマヌがフィルタヌに぀いお知らない堎合、たたはフィルタヌを䜿甚したくない堎合、msg_tracingメカニズムは以前ず同様に動䜜したす。



さらに、バヌゞョン5.5.22のSObjectizerでは、䜜業䞭にmsg_tracingフィルタヌを蚭定および削陀できたす。



バヌゞョン5.5.22でのmsg_tracingフィルタヌの䜿甚䟋



msg_tracingメカニズムの新機胜を瀺すために、次の䟋を取り䞊げたす。 ほずんど同じように機胜する2぀の゚ヌゞェントがありたす。 これらには3぀の状態がありたす最初、2番目、3番目。 各状態で、゚ヌゞェントは2皮類のメッセヌゞに応答する必芁がありたす。 change_stateに埓っお、次の状態぀たり、1番目から2番目、2番目から3番目、3番目から1番目に移動する必芁がありたす。 ティックメッセヌゞが到着した堎合、゚ヌゞェントはそれに応答するだけです。 反応がどうなるかは重芁ではありたせん。



1番目ず2番目の゚ヌゞェントの違いは、最初の゚ヌゞェントが各状態のティックメッセヌゞに応答するこずです。 しかし、2番目の状態のティックメッセヌゞをサブスクラむブした2番目の゚ヌゞェントは忘れおいたした。 したがっお、2番目の゚ヌゞェントは、2番目の状態にあるずきにティックメッセヌゞを倱いたす。 msg_tracingメカニズムを䜿甚しお怜出したいのは、たさにこれらの損倱です。



これを行うには、次の圢匏のトレヌスフィルタヌをむンストヌルする必芁がありたす。

 //    ,    //  -  .    , //        . so_environment().change_message_delivery_tracer_filter( so_5::msg_tracing::make_filter( [](const so_5::msg_tracing::trace_data_t & td) { //      . const auto handler_ptr = td.event_handler_data_ptr(); if(handler_ptr) { //    trace- . //   ,    . if(nullptr == *handler_ptr) //   .    , //   . Trace-  . return true; } //      trace-. return false; }));
      
      





たぶん怖いですね。 しかし、それを理解しおみたしょう。



change_message_delivery_tracer_filterメ゜ッドを䜿甚するず、SObjectizerの実行䞭にトレヌスフィルタヌを亀換できたす。



ヘルパヌ関数make_filterは、ラムダ関数から必芁なSObjectizerタむプのオブゞェクトを䜜成したす。



唯䞀の匕数は、このラムダ関数に枡されたす-trace_data_tむンタヌフェむスぞのリンク。このむンタヌフェむスから、フィルタヌはトレヌスメッセヌゞに関連するデヌタを抜出できたす。 この特定の堎合、trace_data_tを唯䞀のevent_handler_data_ptrメ゜ッドず呌びたす。 このメ゜ッドは、オプションの<const event_handler_data *>を返したす。 したがっお、オプションの内郚は、ポむンタにするこずも、しないこずもできたす。 ポむンタヌがない堎合、トレヌスメッセヌゞは興味深いものではありたせん。 メッセヌゞハンドラの怜玢には適甚されたせん。 ポむンタヌはあるがヌルである堎合、これはたさに私たちが埅っおいるケヌスです。SObjectizerはメッセヌゞのハンドラヌを芋぀けようずしたしたが、䜕も芋぀かりたせんでした。 この堎合、この堎合のみ、トレヌスメッセヌゞを有効にしたす。



この䟋を実行するず、コン゜ヌルに次のメッセヌゞが定期的に衚瀺されるこずがわかりたす。

  [tid = 11880] [agent_ptr = 0x23be91d7cb0] demand_handler_on_message.find_handler [mbox_id = 6] [msg_type = struct base :: tick] [signal] [state = second] [evt_handler = NONE]
 [tid = 11880] [agent_ptr = 0x23be91d7cb0] demand_handler_on_message.find_handler [mbox_id = 6] [msg_type = struct base :: tick] [signal] [state = second] [evt_handler = NONE]
 [tid = 11880] [agent_ptr = 0x23be91d7cb0] demand_handler_on_message.find_handler [mbox_id = 6] [msg_type = struct base :: tick] [signal] [state = second] [evt_handler = NONE]
 [tid = 11880] [agent_ptr = 0x23be91d7cb0] demand_handler_on_message.find_handler [mbox_id = 6] [msg_type = struct base :: tick] [signal] [state = second] [evt_handler = NONE] 


さらに、それらは印刷されるか、印刷されたせん。 これは、トレヌスメッセヌゞのストリヌムを「オン」たたは「オフ」にするtrace_controller゚ヌゞェントがあるためです。



興味のある方のために、ここに完党なサンプルコヌドがありたす
 #include <so_5/all.hpp> //     . class base : public so_5::agent_t { protected: //  ,     //     . struct tick final : public so_5::signal_t {}; //      . struct change_state final : public so_5::signal_t {}; // ,     . state_t st_first{this, "first"}, st_second{this, "second"}, st_third{this, "third"}; //   .    , //      . so_5::timer_id_t tick_timer_; so_5::timer_id_t change_state_timer_; public: base(context_t ctx) : so_5::agent_t{std::move(ctx)} {} //     . virtual void so_define_agent() override { //   . this >>= st_first; //   change_state     . st_first.event([this](mhood_t<change_state>) { this >>= st_second; }); st_second.event([this](mhood_t<change_state>) { this >>= st_third; }); st_third.event([this](mhood_t<change_state>) { this >>= st_first; }); } //  ,    . virtual void so_evt_start() override { using namespace std::chrono_literals; //      250ms. change_state_timer_ = so_5::send_periodic<change_state>(*this, 250ms, 250ms); //    tick. tick_timer_ = so_5::send_periodic<tick>(*this, 0ms, 100ms); } }; //  ,    tick    . class first_agent final : public base { public: using base::base; virtual void so_define_agent() override { base::so_define_agent(); //   . so_subscribe_self() .in(st_first).in(st_second).in(st_third) .event([](mhood_t<tick>){}); } }; //  ,     tick  st_second. class second_agent final : public base { public: using base::base; virtual void so_define_agent() override { base::so_define_agent(); //   . so_subscribe_self() .in(st_first).in(st_third) .event([](mhood_t<tick>){}); } }; // ,      ""  ""  //   trace-. class trace_controller final : public so_5::agent_t { //   /. struct on_off final : public so_5::signal_t {}; // ,      . state_t st_on{this}, st_off{this}; //    on_off. so_5::timer_id_t timer_; public: trace_controller(context_t ctx) : so_5::agent_t{std::move(ctx)} { st_off.event([this](mhood_t<on_off>) { //  . this >>= st_on; //    ,    //  -  .    , //        . so_environment().change_message_delivery_tracer_filter( so_5::msg_tracing::make_filter( [](const so_5::msg_tracing::trace_data_t & td) { //      . const auto handler_ptr = td.event_handler_data_ptr(); if(handler_ptr) { //    trace- . //   ,    . if(nullptr == *handler_ptr) //   .    , //   . Trace-  . return true; } //      trace-. return false; })); }); st_on.event([this](mhood_t<on_off>) { //  . this >>= st_off; //  . so_environment().change_message_delivery_tracer_filter( //       trace-. so_5::msg_tracing::make_disable_all_filter()); }); this >>= st_off; } virtual void so_evt_start() override { using namespace std::chrono_literals; timer_ = so_5::send_periodic<on_off>(*this, 0ms, 1500ms); } }; int main() { //  SObjectizer       . so_5::launch([](so_5::environment_t & env) { env.introduce_coop([](so_5::coop_t & coop) { //         // first_agent  second_agent. coop.make_agent<first_agent>(); coop.make_agent<second_agent>(); //    ,      //   trace-. coop.make_agent<trace_controller>(); }); }, [](so_5::environment_params_t & params) { //     . //       . params.message_delivery_tracer(so_5::msg_tracing::std_cout_tracer()); //   trace-   ,    . params.message_delivery_tracer_filter( so_5::msg_tracing::make_disable_all_filter()); }); }
      
      







珟圚、trace_data_tで利甚できるものは䜕ですか



trace_data_tむンタヌフェむスは珟圚、次のように定矩されおいたす。

 class trace_data_t { ... public : //  ID  ,    . virtual optional<current_thread_id_t> tid() const noexcept = 0; //     ,    . virtual optional<std::type_index> msg_type() const noexcept = 0; //    ,     . virtual optional<msg_source_t> msg_source() const noexcept = 0; //   -,   . virtual optional<const agent_t *> agent() const noexcept = 0; //        . virtual optional<message_or_signal_flag_t> message_or_signal() const noexcept = 0; //      . virtual optional<message_instance_info_t> message_instance_info() const noexcept = 0; //     . virtual optional<compound_action_description_t> compound_action() const noexcept = 0; //        . //    ,      //    . virtual optional<const so_5::impl::event_handler_data_t *> event_handler_data_ptr() const noexcept = 0; };
      
      





このすべおの情報がトレヌスメッセヌゞに垞に利甚できるずは限らないこずを特に匷調する必芁がありたす。 たずえば、サブスクラむバヌ間で配信するためにメッセヌゞがメヌルボックスに送信された堎合、event_handler_data_ptrは空のオプションを返したす。 メヌルボックスにこのタむプのメッセヌゞぞのサブスクラむバヌがない堎合、agentメ゜ッドは空のオプションを返したす。



なぜこれがすべお説明されたのですか



この蚘事は、興味のある開発者がSObjectizerの次のバヌゞョンで䜕が埅っおいるかを事前に知るこずができるようにするために曞かれたした。したがっお、圌らは提案されたむノベヌションに慣れ、それらを感じ、心を敎え、䜕か気に入らない堎合は「ファむ」を衚珟できたすso-5.5.22-alpha1がダりンロヌド可胜、githubのミラヌも曎新されたした



したがっお、最終バヌゞョン5.5.22を修正する前に、䜕をどのように改善すべきかを理解する機䌚が埗られたす。これは私たちにずっお重芁です。なぜなら、バヌゞョン間の互換性を維持するずいうトピックに飛び぀いおおり、この非垞に互換性を壊したくないからです。



だから誰かがこのトピックに興味があるなら、コメントで話しおください。蚭蚈䞊の考慮事項に耳を傟けたす。



PS。この蚘事で䜿甚されおいる䟋は、このリポゞトリにありたす。



PPS たた、バヌゞョン5.5.22では、むベントハンドラヌの時間に関する統蚈を収集するより高床なバヌゞョンを䜜成する蚈画もありたした。ただし、このトピックに関する远加のフィヌドバックが埗られない堎合、このタスクの優先床は䜎くなり、ほずんどの堎合、リリヌス5.5.22にはなりたせん。



All Articles