単一のプロセス (P1) から出力を取得し、他のプロセス (P2 および P3) を使用して並列タスクを実行しようとしています。ここまでは至ってシンプル。
これを行うには、P2 と P3 を P1 の単一の出力ポートに接続します。私の考えでは、これは、P2 と P3 の両方が同時に並行して取得するパケットを、P1 が出力ポートから送信することを意味するはずです。
私が見つけたのは、P2 と P3 が並行して開始されておらず、代わりに一方のプロセスが他方のプロセスが完了するまで待機することです (または、少なくとも私にはそう思われます)。
たとえば、JSON 入力を受け取り、同時にタイムスタンプを取得して JSON を解析する単純なグラフを次に示します。JSON の解析後に別のタイムスタンプが取得されます。これは、JSON 解析にかかった時間を計算するための基本的な方法として使用されます。
out ポートからの接続の順序に注意してくださいajax/Get
(タイムスタンプ接続が最後に追加されました)。
この場合、タイムスタンプの差は約 5 ミリ秒です。これは、NoFlo 以外の環境で JSON 解析にかかる時間とほぼ一致します (実際には、何らかの理由で NoFlo では少し長くなります)。
同じグラフを見てみましょう。ただし、今回はajax/Get
出力ポートからの接続順序が変更されています (解析接続が最後に追加されました)。
今回のタイムスタンプの差は約 40 ~ 50 ミリ秒で、これは明らかに大きな差であり、NoFlo の外部での解析よりもはるかに大きくなっています。
誰かが次の点に光を当てることができれば、本当に感謝しています。
- 接続順によってタイミングがこんなに違うのはなぜですか?
- からの 2 つの接続
ajax/Get
がトリガーされ、並行して実行されるようにするにはどうすればよいですか (つまり、相互に待機しません)。
参考になる場合は、FlowHub からのグラフの JSON エクスポートを次に示します。
また、CLI を使用して簡単なグラフを作成し、グラフの流れをよりよく理解して、おそらくこれを引き起こしている原因を明らかにすることができました。
# This executes in the correct order, though likely by
# coincidence and not due to true parallelisation.
#
# Time1 is run and outputted before Time2.
#
Read(filesystem/ReadFile) OUT -> IN Time1(objects/GetCurrentTimestamp)
Read OUT -> IN Parse(strings/ParseJson)
# This executes the entire Parse path before going back to grab
# and output Time1.
#
# Time1 is run and outputted *after* Time2
# Read doesn't send a disconnect message to Parse until *after*
# Time 1 is outputted.
#
# Read doesn't send a disconnect message to Time1 until *after*
# the Parse path has finished disconnecting.
#
# Read(filesystem/ReadFile) OUT -> IN Parse(strings/ParseJson)
# Read OUT -> IN Time1(objects/GetCurrentTimestamp)
Time1 OUT -> IN Display1(core/Output)
Parse OUT -> IN Time2(objects/GetCurrentTimestamp)
Time2 OUT -> IN Display2(core/Output)
'sample.geojson' -> IN Read
to の前に定義されたRead
to接続で実行すると、ネットワークは正常に動作しますが、切断を開始する前に他のすべてが完了するまで待機することに気付きました(そうですか?):Time1
Read
Parse
Read
DATA -> ENCODING Read() CONN
DATA -> ENCODING Read() DATA
DATA -> ENCODING Read() DISC
DATA -> IN Read() CONN
DATA -> IN Read() DATA
DATA -> IN Read() DISC
Read() OUT -> IN Time1() CONN
Read() OUT -> IN Time1() < sample.geojson
Read() OUT -> IN Parse() CONN
Read() OUT -> IN Parse() < sample.geojson
Parse() OUT -> IN Time2() CONN
Parse() OUT -> IN Time2() < sample.geojson
Read() OUT -> IN Time1() DATA
Time1() OUT -> IN Display1() CONN
Time1() OUT -> IN Display1() DATA
1422549101639
Read() OUT -> IN Parse() DATA
Parse() OUT -> IN Time2() DATA
Time2() OUT -> IN Display2() CONN
Time2() OUT -> IN Display2() DATA
1422549101647
Read() OUT -> IN Time1() > sample.geojson
Read() OUT -> IN Parse() > sample.geojson
Parse() OUT -> IN Time2() > sample.geojson
Read() OUT -> IN Time1() DISC
Time1() OUT -> IN Display1() DISC
Read() OUT -> IN Parse() DISC
Parse() OUT -> IN Time2() DISC
Time2() OUT -> IN Display2() DISC
Read
toParse
接続が最初に定義されるように順序を切り替えると、すべてがうまくいかず、パス全体が完了するまでTime1
パケットが送信されません(実際には今以降です):Read
Parse
Time1
Time2
DATA -> ENCODING Read() CONN
DATA -> ENCODING Read() DATA
DATA -> ENCODING Read() DISC
DATA -> IN Read() CONN
DATA -> IN Read() DATA
DATA -> IN Read() DISC
Read() OUT -> IN Parse() CONN
Read() OUT -> IN Parse() < sample.geojson
Parse() OUT -> IN Time2() CONN
Parse() OUT -> IN Time2() < sample.geojson
Read() OUT -> IN Time1() CONN
Read() OUT -> IN Time1() < sample.geojson
Read() OUT -> IN Parse() DATA
Parse() OUT -> IN Time2() DATA
Time2() OUT -> IN Display2() CONN
Time2() OUT -> IN Display2() DATA
1422549406952
Read() OUT -> IN Time1() DATA
Time1() OUT -> IN Display1() CONN
Time1() OUT -> IN Display1() DATA
1422549406954
Read() OUT -> IN Parse() > sample.geojson
Parse() OUT -> IN Time2() > sample.geojson
Read() OUT -> IN Time1() > sample.geojson
Read() OUT -> IN Parse() DISC
Parse() OUT -> IN Time2() DISC
Time2() OUT -> IN Display2() DISC
Read() OUT -> IN Time1() DISC
Time1() OUT -> IN Display1() DISC
これが正しい動作である場合、一方が他方をブロックせずに 2 つのブランチを並行して実行するにはどうすればよいですか?
すべてのコンポーネントを非同期にしてみました。その両方を試し、WirePattern を使用して、複数の出力ポートを作成し、それらすべてを一度にデータを送信しようとしました。喜ばしいことではありません - それは常に、最初のエッジが接続される順序に帰着します。ViziCitiesでのNoFloの使用を完全にブロックしているため、これで髪を引っ張っています:(