2015-10-28 19 views
7

Đây là một tình huống phổ biến mà tôi gặp phải, trong đó tôi có hai (hoặc nhiều hơn) diễn viên nhận được một số dữ liệu không đồng bộ, và sau đó tôi cần thực hiện một thao tác khi chúng hoàn tất.Akka.net chờ đợi nhiều phần dữ liệu

Mẫu phổ biến để làm điều này là gì?

Dưới đây là một ví dụ đơn giản.

public MasterActor : ReceiveActor 
{ 
    public MasterActor() 
    { 
      Initialize(); 
    } 

    public void Initiaize() 
    { 
     Receive<DoSomeWork>(_ => 
     { 
       var actor1 = Context.ActorOf(Props.Create(() => new Actor1()); 
       var actor2 = Context.ActorOf(Props.Create(() => new Actor2()); 

       // pretend these actors send responses to their senders 
       // for sake of example each of these methods take between 1 and 3 seconds 
       actor1.Tell(new GetActor1Data()); 
       actor2.Tell(new GetActor2Data()); 
     }); 

     Receive<Actor1Response>(m => 
     { 
      //actor 1 has finished it's work 
     }); 

     Receive<Actor2Response>(m => 
     { 
      //actor 2 has finished it's work 
     }); 
    } 
} 

Để khởi động, tôi gửi MasterActor thông báo DoSomeWork.

Cách phổ biến để thực hiện thao tác khi tôi có cả số Actor1Response và số Actor2Response là gì.

Tôi không thực sự muốn có logic trong mỗi bộ xử lý nhận được kiểm tra nếu người kia đã hoàn thành hoặc bất cứ điều gì như thế. Tôi đoán những gì tôi đang nghĩ về một cái gì đó tương tự như một phương pháp Task.WaitAll().

Tôi có đang tấn công vấn đề không đúng cách không? Tôi có cần phải viết lại các diễn viên theo một cách khác không?

Bất kỳ mẫu hoặc giải pháp phổ biến nào đều tuyệt vời.

Trả lời

3

Giải pháp phổ biến cho việc này là gắn một số loại tương quan được chia sẻ bởi cả thư yêu cầu và phản hồi - vì diễn viên xử lý thư đồng bộ, điều này có thể không được kiểm tra.

Bạn chỉ cần lưu trữ id tương quan trong một số cấu trúc dữ liệu (hãy đặt) bên trong người gọi và khi nhận được phản hồi, hãy xóa id tương quan khỏi tập hợp. WaitAll hoàn thành về cơ bản khi đặt trống hoặc hết thời gian chờ.

Bạn có thể đặt thời gian chờ bằng cách sử dụng Context.SetReceiveTimeout(timeout), cách này diễn viên sẽ tự gửi một phương thức ReceiveTimeout sau khi chưa nhận được bất kỳ tin nhắn nào trong một thời gian.

Hành vi này khá chung chung và có thể được tóm tắt khá dễ dàng.

2

Cách đơn giản nhất để thực hiện việc này là tăng số lượng "phiếu bầu" lên tổng thể khi mỗi trẻ trả lời. Khi bỏ phiếu == con đếm, bạn đã hoàn tất.

Bạn có thể mở rộng điều này để chỉ đếm tin nhắn đầu tiên từ mỗi đứa trẻ, hoặc một tin nhắn cụ thể từ mỗi đứa trẻ, nhưng tất cả đều sôi xuống để đếm cuối cùng.

Các vấn đề liên quan