2017-03-23 22 views
1

我試圖將工作的C#示例移植到OOP version of F#如何使用F實現Props.Create#

遠程參與者(在單獨的進程上)沒有接收消息。

我收到以下錯誤:

[ERROR][3/23/2017 4:39:10 PM][Thread 0008][[akka://system2/system/endpointManage 
r/reliableEndpointWriter-akka.tcp%3A%2F%2Fsystem1%40localhost%3A8090-1/endpointW 
riter#1919547364]] AssociationError [akka.tcp://[email protected]:8080] <- akka. 
tcp://[email protected]:8090: Error [Object reference not set to an instance of 
an object.] [ at Akka.Serialization.Serialization.FindSerializerForType(Type o 
bjectType) 
    at Akka.Remote.Serialization.DaemonMsgCreateSerializer.GetArgs(DaemonMsgCreat 
eData proto) 
    at Akka.Remote.Serialization.DaemonMsgCreateSerializer.FromBinary(Byte[] byte 
s, Type type) 
    at Akka.Serialization.Serialization.Deserialize(Byte[] bytes, Int32 serialize 
rId, String manifest) 

這裏的工作C#版本:

use system = ActorSystem.Create("system1", config) 
let reply = system.ActorOf<ReplyActor>("reply") 

let props1 = Props.Create(fun() -> SomeActor() :> obj) 
let props2 = Props.Create(fun() -> SomeActor() :> obj) 
let props3 = Props.Create(fun() -> SomeActor() :> obj) 

let remote1 = system.ActorOf(props1.WithRouter(FromConfig.Instance), "remoteactor1") 
let remote2 = system.ActorOf(props2.WithRouter(FromConfig.Instance), "remoteactor2") 
let remote3 = system.ActorOf(props3.WithRouter(FromConfig.Instance), "remoteactor3") 

let hashGroup = system.ActorOf(Props.Empty.WithRouter(ConsistentHashingGroup(config))) 
Task.Delay(500).Wait(); 

let routee1 = Routee.FromActorRef(remote1); 
hashGroup.Tell(new AddRoutee(routee1)); 

let routee2 = Routee.FromActorRef(remote2); 
hashGroup.Tell(new AddRoutee(routee2)); 

let routee3 = Routee.FromActorRef(remote3); 
hashGroup.Tell(new AddRoutee(routee3)); 

Task.Delay(500).Wait(); 

for i = 0 to 5 do 
    for j = 0 to 7 do 

     let message = new HashMessage(j, sprintf "remote message: %i" j); 
     hashGroup.Tell(message, reply); 

Console.ReadLine() |> ignore 

using (var system = ActorSystem.Create("system1", config)) 
{ 
    var reply = system.ActorOf<ReplyActor>("reply"); 

    //create a remote deployed actor 
    var remote1 = system.ActorOf(Props.Create(() => new SomeActor()).WithRouter(FromConfig.Instance), "remoteactor1"); 
    var remote2 = system.ActorOf(Props.Create(() => new SomeActor()).WithRouter(FromConfig.Instance), "remoteactor2"); 
    var remote3 = system.ActorOf(Props.Create(() => new SomeActor()).WithRouter(FromConfig.Instance), "remoteactor3"); 

    var hashGroup = system.ActorOf(Props.Empty.WithRouter(new ConsistentHashingGroup(config))); 

    Task.Delay(500).Wait(); 

    var routee1 = Routee.FromActorRef(remote1); 
    hashGroup.Tell(new AddRoutee(routee1)); 

    var routee2 = Routee.FromActorRef(remote2); 
    hashGroup.Tell(new AddRoutee(routee2)); 

    var routee3 = Routee.FromActorRef(remote3); 
    hashGroup.Tell(new AddRoutee(routee3)); 

    Task.Delay(500).Wait(); 

    for (var i = 0; i < 5; i++) 
    { 
     for (var j = 0; j < 7; j++) 
     { 
      var message = new SomeMessage(j, $"remote message: {j}"); 
      hashGroup.Tell(message, reply); 
     } 
    } 

    Console.ReadLine(); 
} 

這裏使用OOP的端口,以F#

問:

是我該上溯造型SomeActor對象類型調用Props.Create方法是什麼時候?

let props1 = Props.Create(fun() -> SomeActor() :> obj) 
let props2 = Props.Create(fun() -> SomeActor() :> obj) 
let props3 = Props.Create(fun() -> SomeActor() :> obj) 

上面的代碼是我意識到的唯一區別。

唯一的區別是tcp路徑。

C#的TCP:

remote { 
    dot-netty.tcp { 
     port = 8090 
     hostname = localhost 
    } 

F#的TCP:

remote { 
     helios.tcp { 
      port = 8090 
      hostname = localhost 
     } 
+2

不確定它是否有材料差異,但你的for循環在F#中的大1個元素(因爲你在C#中檢查'<'而不是'<=')。 – kvb

+0

謝謝你的觀察kvb。 –

+0

如果你不向'obj'上傳會發生什麼?看起來好像有一堆'Create'的覆蓋,所以如果upcast強迫使用另一個,我不會感到驚訝,這可以解釋結果。 – kvb

回答

3

道具目的是一種用於目標的演員的創建過程的描述符。此外,它必須是可序列化的,因爲它有時可能包含在通過網絡傳遞的消息中。

爲了以這種方式工作,Props在內部描述了(actor-type,actor-constructor-arguments)形式的actor構造。 Props.Create(() => new Actor())在這裏只是一個幫手:它的實際作用是將構造函數表達式解析爲具有參數的類型信息。這就是爲什麼它僅適用於new Actor()表達式。

您的F#代碼的問題在於您將演員創建定義爲F#函數,而解構器不知道如何處理。你可能仍然想創建你的演員使用:

Props.Create(typeof<Actor>, [| arg1; arg2 |]) 

但你需要保持自己的構造函數參數的正確性。您也可以使用Akkling,即typed version of props