2016-04-20 10 views
1

ここでは、俳優200人を作成して最後の100を送信する前に"first"メッセージを最初に送信します。"second"最初の100百人の俳優が起こらない第2グループにメッセージを送信する前に(すなわち、印刷して終了)を完了するために私が好きな何F#Akka - 次のグループを開始する前に1組の俳優が終了するのを待ちます。

open System 
open Akka.Actor 
open Akka.Configuration 
open Akka.FSharp 

let system = System.create "test" (Configuration.defaultConfig()) 

let myActor (mailbox: Actor<_>) = 
    actor { 
     let rand = System.Random() 
     let! message = mailbox.Receive() 
     match message with 
     | "first" -> printfn "first group" 
     | _ -> printfn "second group" 
     Thread.SpinWait (rand.Next(100,1000)) 
    } 
let actorArray = Array.create 200 (spawn system "myActor" myActor) 

{0..199} |> Seq.iter (fun a -> 
    actorArray.[a] <- spawn system (string a) myActor 
) 

// First group 
{0..100} |> Seq.iter(fun a -> 
    actorArray.[a] <! "first" 
    () 
) 
// Second group 
{101..199} |> Seq.iter(fun a -> 
    actorArray.[a] <! "second" 
    () 
) 

です。

私はAkka's F# monitoringモジュールを見始めましたが、実装方法はよく分かりません。

+3

まず、システムを作成するために間違ったAkkaメソッドを呼び出していると思います。 [Akka F#API docs](http://getakka.net/docs/FSharp%20API#monitoring)は、F#からそれを使用しようとするならば、 'Akka.FSharp.System.create'関数を呼び出すと言っていますが、代わりに 'Akka.Actor.ActorSystem.Create'と呼んでいます。私はAkkaを知らないので、残りのお手伝いができないかもしれませんが、私は少なくともあなたがその間違いを犯すのを助けることができます。 – rmunn

+0

アドバイスをいただきありがとうございます、両方の行が同じ動作をしているように見えますが、私はそれを仕様に保つように編集しました! – Darkstarone

+1

私は、違いが微妙で、あなたがまだそれらを見ることはないという印象を文書から得ていますが、F#版では、後でF#引用(「<@ @>」表記)を使うことができます。 – rmunn

答えて

1

私は解決策を作りましたが、それが最も慣れているかどうかはわかりませんが、それは仕事です!本質的には

open System 
open Akka.Actor 
open Akka.Configuration 
open Akka.FSharp 

let system = System.create "MySystem" (Configuration.defaultConfig()) 

let myActor (mailbox: Actor<_>) = 
    actor { 
     let rand = System.Random() 
     let! message = mailbox.Receive() 
     let sender = mailbox.Sender() 
     match message with 
     | "first" -> printfn "first group"  
     | _ -> printfn "second group" 
     Thread.SpinWait (rand.Next(100,1000)) 
     sender <! "Done" 
    } 

let myMonitor (mailbox: Actor<_>) = 
    let mutable i = 99 
    let actorArray = Array.create 200 (spawn system "myActor" myActor) 
    {0..199} |> Seq.iter (fun a -> 
     actorArray.[a] <- spawn system (string a) myActor 
     () 
    ) 
    // First group 
    {0..100} |> Seq.iter(fun a -> 
     actorArray.[a] <! "first" 
     () 
    ) 
    let rec loop() = 
     actor { 
      let! message = mailbox.Receive() 
      match message with 
      | _ -> 
       i <- (i - 1) 
       if (i = 0) then 
        // Second group 
        {101..199} |> Seq.iter(fun a -> 
         actorArray.[a] <! "second" 
         () 
        ) 
      return! loop() 
     } 
    loop() 

let mon = spawn system "myMon" myMonitor 

何が起こるかは環境を設定し、タスク外その再帰ループの最初のセットを開始しますmyMonitor外部の俳優です。タスクのアクターは、完了すると"Done"を送信し、これはmyMonitor再帰ループ内で処理されます。

myMonitorは、最初のブロックからすべてのメッセージを受信すると、2番目のブロックを開始します。

関連する問題