タスク (1)

ポエニーのcoreプログラムは、D言語で書かれていて、プラットホームネイティブなスレッドで構成されている(と信じてる)。
俺は、このスレッド達のこと『タスク』と呼んでいる。
(nyの技術の影響。winnyは自前でスケジューラ書いているみたい)

タスクたちは、タスク間メッセージキューを使ってコマンドをやり取りしながら、互いに協力し合って仕事をこなしてる。

今日はこの最も重要なタスク構成について考えてみた。
まず、一番重要でプログラムのネックにもなっているノードタスクんについて。

ノードタスクん

通信用コネクションの管理とノード情報の管理をしている。
ノードタスクんが行っている仕事の詳細は、

@ 1. 外向けリスナーポートの監視
下流ノードからの検索リンク接続や転送リンク接続(テスト接続含む)を受け入れる。
接続認証後、不要ならノードならノード情報と切断コマンドを送って切断する。
接続を維持する接続は、コネクションリストに入れておく。

@ 2. 接続済みコネクションの監視
接続済みのノードを監視して、受信可能なデータがあれば受信する。
受信したデータは、ヘッダ部分(コマンドコード、バイト長)だけ分解して、
ルーティングタスクへ投げる。
ノードタスクんは、「上流検索リンク」「下流」「転送リンク」の3つのコネクションリストを持っており、これら全てを定期的に監視する。

@ 3. 上流検索リンクの探索
保持しているノード情報(初期ノード含む)から検索リンク候補を選タスクして接続試行を行う。
接続に成功したら、認証を行い、不要なノードならノード情報と切断コマンドを送って切断する。
接続を維持する接続は、コネクションリストに入れておく。

@ 4. UI
UIタスクから、ポート番号変更命令を受ける。
この命令を受けると、指定されたポートが使用可能か調べ、使用可能であれば接続中の全ノードを切断して、外向けリスナーポートのポート番号を変更する。

@ 5. コマンド送信
各タスクから送信された送信パケットを接続済みノードへ送信する。
現在は、クエリタスクからの検索要求、拡散クエリ要求を受け取る。

@@

と、かなりがんばりすぎなノードタスクん。

今の考えだと、2と3を別タスクにする予定。
特に3は、かなりの負担になっていて、受信タイムアウト2秒で検索リンク候補を相手にコネクト、接続認証を行うため、最悪の場合で8秒近く返って来ない。
この間に接続済みノードから送信されてきたコマンドは全て保留、新しい接続ノードも全て保留、となっているため、かなり通信効率が悪い。
UIからのポート番号変更に時間がかかることがあるのも、ノードタスクんが上流検索リンク探索から返ってこないからである。

2は、サイズの大きなコマンドを受信する際に時間がかかることがあるので、別にしたい。
ただ、これらを別にすると、現在単一タスクで管理しているノード情報などの資源を別タスクに送ったり、受け取ったりしないといけないが、これはホントちょっとしたことだと思っている…。