Như đã trình bày trong bài Giới thiệu về Apache Akka, các Actor trao đổi với nhau thông qua message. Ở đây, message có thể là bất kỳ loại object nào nhưng chúng phải immutatble(không thể bị thay đổi). Thông thường các object như String, Int, Boolean đều là immutable objects.

Trong bài tutorial này, chúng ta sẽ tìm hiểu về 3 hoạt động trao đổi message trong Akka là Message Sending, Replying và Forwarding (Message Receiving đã được để cập trong bài Viết chương trình Akka cơ bản):

* Message Sending: trong Akka, message có thể được gửi bằng một trong hai phương pháp sau:

– tell() hoặc dùng dấu “!”: hoạt động theo nguyên tắc fire-forget (gửi tin nhắn nhưng không đợi tin nhắn phản hồi). Nếu message được gửi từ một Actor thì sender là tên của Actor đó, nếu không thì mặc định sender sẽ là deadLetters

– ask() hoặc dùng dấu “?”: hoạt động theo nguyên tắc Send-And-Receive-Future (Future biểu thị cho các phản hồi có thể nhận được. nếu Future không nhận được sau một khoảng thời gian xác định thì sẽ xảy ra lỗi AskTimeOutException). Khác với tell(), ask() không sử dụng sender(), do đó tến của sender là Actor.noSender(xem thêm tại đây)

* Message Replying: Để phản hồi lại tin nhắn cho người gửi, chúng ta có thể sử dụng hàm sender(). Hàm này trả về kết quả là ActorRef của sender Actor (việc gửi tin nhắn phải hồi có thể thực hiện theo 1 trong 2 cách đã nêu ở trên)

* Message Forwarding: Akka cho phép người dùng có thể forward message từ actor này sang actor khác. Trong trường hợp này, address/reference của một sender Actor gốc vẫn được giữ nguyên dù message được truyền qua các Actor trung gian.

Tiếp theo, chúng ta sẽ viết chương trình mô tả 3 hoạt động trao đổi message trên bằng cách sử dùng hàm ask() để gửi một tin nhắn từ hàm main() của chương trình tới MessageActor. Sau khi nhận được tin nhắn, MessageActor sẽ gửi phản hồi lại cho sender đồng thời gửi tin nhắn tới ChildActor bằng cả hai phương pháp là forward() và tell() để so sánh sự khác nhau giữa 2 phương pháp này. Các bạn tham khảo full code của chương trình dưới đây.

Chạy chương trình trên ta được kết quả sau:

Do hàm ask() sử dụng Actor.noSender nên tên của sender của message gửi từ hàm main là $a (nếu ta gửi các tin nhắn tiếp theo thì tên sẽ là $b, $c,…). Ngoài ra khi sử dụng hàm forward() thì sender gốc của message vẫn được giữ nguyên (ở đây là $a). Trong khi đó, nếu ta sử dụng hàm tell() thì sender gốc này đã bị thay thế bởi Actor sử dụng hàm tell() (ở đây là MessageActor).

Tháng Một 14, 2019
ITechSeeker