2016-05-08 17 views
1

を管理することは、私はそうのような単純な機能を持っていると仮定します。のClojure:個々のスレッド

(defn process-files 
    "Take file name and read data" 
    [file] 
    (let [data (slurp file) 
     rows (rest (c/parse-csv data))] 
     (doseq [row rows] 
      (future (call-url (nth row 3 nil))) 
    )) 

その後、CGIスクリプトへの呼び出しを行うれ、コールURLにIDを渡します。 cgiスクリプトは、IDに基づいて文書をキューに入れ、処理が完了するのを待ちます。私の目的のために、プロセスを完了するのを待つCGIコールの部分は、ブラウザを介してサービスにぶつかる誰かにとって興味深いだけです。

私がしたいのは、100スレッドをキックオフすることです。実行するcgiスクリプトの 'put document into queue'フェーズで十分待ってから、それらのスレッドをシャットダウンします完了するのを待って)、100行の次のバッチに進みます。すすぎ、繰り返します。

(shutdown-agents)は、プログラム全体を強制終了し、私のreplを殺すという点でsystem.exitのように動作するようです。

(future-cancel)は単一のスレッドで動作しますが、スレッドのバッチをキャンセルする方法がわかりません。

洞察が得られるでしょう。

答えて

2

「実行するcgiスクリプトの「キューに文書を入れる」のに十分な長さを待っている」ことは良い考えではないと思います。あなたはどのように「十分に長く」定義できますか?どのくらいの時間がかかるか見積もり、エンドポイントへのHTTP要求を閉じるかタイムアウトさせようとするかもしれませんが、CGIスクリプトを実行しているサーバーが少し遅くなったらどうしますか?あなたのCGIサービスに二つの別々のエンドポイントを公開する必要があります私の意見で

:ユーザーが処理を待つことになるUIインターフェイスのために露出されて

  • 1は
  • にある別々の1を完了するために

このような設計は、処理を信頼できるものにし、クライアントアプリケーションをはるかに簡単にします(スレッドは必要に応じてブロックされ、待機します。長いそのために設計されていない方法で既存のエンドポイントを使用するための回避策は必要ありません)。

CGIエンドポイントを変更できない、または変更しない場合は、HTTPクライアントライブラリのタイムアウト機能を使用します。たとえば、要求レベルで動作するhttpkit clientには、のいずれかのclj-httpまたは:timeoutパラメータを使用できます。しかし、タイムアウトがネットワークレベルで動作し、受信バイトがタイムアウトカウンタをリセットするため、常に信頼できるとは確信できません。

応答を無視して応答を無視する非同期クライアントをブロックして使用することもできます。 For example using httpkit library

(let [response-future (http/post "http://example.com/cgi-bin/abc")] 
    (deref response-future 10000 :time-out)) 

http/postは、サーバーを呼び出し、応答が含まれます将来のオブジェクトを返します。 derefを使用して応答をブロックして待機しますが、指定されたタイムアウト(ミリ秒単位)を超えることはできません。 10秒以内に応答がない場合は、:time-outの値が返されます(戻り値は無視できます)。

+0

通常、cgiの戻り部分は、ドキュメントがPDFに変換されるのを待ってブラウザに表示します。その待機部分が終了すると、バックエンドプロセスは、変換されたドキュメントをエンドユーザが消費するための「変換済みドキュメント」ファイラにエスコートするので、バックエンドで各ドキュメントを待つことには関係しません。私はプッシュ機能をハイジャックして終了したいだけです。私たちが離れていくレガシーシステムなので、既存のコードで不必要な修正を避けています。フロントエンドは1文書あたり約10秒です。私は待機しています。 –

+0

私はasync httpコールとタイムアウトを使用して、可能な解決策を追加しました。 –

+0

ありがとうございます。私があなたが言及したアプローチを検討します。 –

関連する問題