0

Mailbox タイプはカプセル化されており、MailboxProcessor を使用しないと使用できないことに気付きました。

メッセージを投稿できるエージェントを持つには、単一のタイプの単一のメールボックスを持つ (または、既存の MailboxProcessor を風変わりな方法で使用する) 必要があることを意味します。

1 つのワークフローに対して複数のメールボックスを使用すると、本質的に不適切な設計になることを理解する必要がありますか? Ccr は明らかにそのレベルの自由を提供します。

編集:ダニエルが指摘したように、複数のメッセージタイプを送信したい場合、DUは問題をエレガントに解決します-そして、私が過去にそれをしなかったわけではありません.

しかし問題は、それを行うのはコードの匂いではないかということです。時間の経過とともにエージェントに送信されるメッセージの種類が増えると、責任が大きくなりすぎませんか? この情報が決して公開されないように、エージェントがインターフェイスの背後で消費するメッセージの種類を常にカプセル化することが重要だと思うことがあります。

4

4 に答える 4

5

と CCRを使用する F# エージェントMailboxProcessorは異なるプログラミング モデルを実装していると思いますが、どちらも同じように強力であると信じています。メールボックスを中心に構築された F#。CCR に基づくプログラミング モデルは、 COmega (古い MSR プロジェクト)などの結合計算に基づくさまざまな言語で、おそらくより明確に記述されています。

たとえば、COmega エージェントと F# エージェントを使用して、1 プレース バッファーの実装を比較できます。

public class OnePlaceBuffer {
  private async empty();
  private async contains(string s);

  public OnePlaceBuffer() { empty(); }
  public void Put(string s) & empty() {
    contains(s);
  }
  public string Get() & contains(string s) {
    empty();
    return s;
  }
}

emptyこの例では、非同期メソッドはメールボックスのように動作し (つまり、 、containsPutおよびの 4 つがありますGet)、ボディはハンドラーのように動作し、メールボックスの組み合わせに値が含まれている場合 (つまり、空のバッファーに入れたり、フルバッファから取得したとき)。F# では、次のように使用および記述できます。MailboxProcessor

type Message<'T> =
  | Put of 'T * AsyncReplyChannel<unit>
  | Get of AsyncReplyChannel<'T>

MailboxProcessor.Start(fun agent ->
  let rec empty = agent.Scan(function
    | Put(v, repl) -> repl.Reply(); Some(full(v))
    | _ -> None)
  and full v = agent.Scan(function
    | Get repl -> repl.Reply(v); Some(empty)
    | _ -> None)
  empty )

2 つの実装は同じ考え方を表現していますが、少し異なる方法で表現されています。F# では、emptyfullはエージェントのさまざまな状態を表す 2 つの関数であり、エージェントに送信されるメッセージは、エージェントの状態 (保留中の作業) のさまざまな側面を表します。COmega の実装では、プログラムのすべての状態がメールボックスによってキャプチャされます。

MailboxProcessorエージェントの状態を、処理が必要な直接のメッセージから分離することで、F# について考えるのが少し簡単になるかもしれないと思いますが、それは根拠のないただの考えです...

最後に、MailboxProcessorF# で使用する現実的なアプリケーションでは、より多くの数を使用する可能性が非常に高く、それらは何らかの方法で接続されます。たとえば、パイプライン処理の実装は、複数のMailboxProcessorインスタンスを使用するアプリケーションの良い例です (もちろん、すべてのインスタンスには単純な実行中の非同期ワークフローが関連付けられています)。例については、この記事を参照してください。

于 2011-12-12T23:37:26.470 に答える
1

一般に、メッセージの種類は、単一のメールボックス内でさまざまな種類のメッセージを許可する識別結合です。あなたの場合はうまくいきませんか?

于 2011-12-12T22:30:06.490 に答える
1

ISubjectReactive Extensionsのタイプのようなものを使用しない限り、1 つのタイプのメッセージのみを使用してメールボックスを正常に操作できるとは思えません。メッセージにはさまざまな形があり、すべてが重要です。私が考えることができる2つの主な例は次のとおりです。

  1. 制御メッセージ - キューのクリア、特定のメッセージの検索、シャットダウン、子プロセスのスピンアップなど、メールボックスが実行する操作を示します。
  2. データ メッセージ - 送受信 (Put / Get) は、これらの一般的なタイプです。

データ メッセージを特定のタイプに制限する可能性が最も高いと考えるのは正しいですが、技術的には DU は多くの選択肢を持つ 1 つのタイプです。L'Agent での最初の動的なアプローチで Luca と同じアプローチを取るとしたら、彼も私も、1 つのメールボックスにあまりにも多くのタイプがあるのは少し難しいことに同意すると思います。

于 2011-12-13T16:21:44.757 に答える
0

探していたものが見つかったのではないかと思います。私は Rich Hickey の講演 (Are we there yet) を少なくとも 5 回聞いたことがありますが、彼のアプローチは私が抱えていた設計上の懸念の多くを解決してくれると信じています。明らかに、これは F# メールボックスまたは CAS 参照で実装できます。

私は本当にそれをお勧めします。フィードバックをいただければ幸いです。

于 2012-06-20T17:55:01.207 に答える