2013-07-28 39 views

Trả lời

15

Bạn thực sự không cần phải đăng ký ClusterDomainEvent hoặc MemberEvent. Bạn chỉ có thể truy cập vào state thành viên của phần mở rộng cụm, ví dụ:

val cluster = akka.cluster.Cluster(context.system) 

val members = cluster.state.members.filter(_.status == MemberStatus.Up) 
+1

Theo kinh nghiệm của tôi (và tôi nghĩ rằng điều này được đề cập trong tài liệu ở đâu đó) nhận trạng thái theo cách này không đảm bảo được đồng bộ hóa. Nếu bạn cần một bức tranh chính xác hơn về trạng thái bạn cần làm một cái gì đó như Patrik Nordwall gợi ý, phân tích các sự kiện trong một người nghe cụm. – jm0

+0

Theo kinh nghiệm của tôi, bạn không thể kết hợp hai thành ngữ trong cùng một diễn viên. Trả lời các sự kiện Cluster trong việc nhận được đảm bảo ở phía sau trạng thái cụm thực tế do độ trễ của các thư treo xung quanh trong các hộp thư. –

+0

thx để làm rõ - trường hợp sử dụng của tôi mặc dù là tôi cần phải thực hiện phân giải bộ não phân chia khi một thành viên bị loại bỏ, vậy làm cách nào để cập nhật trạng thái mới nhất trong tình huống này nếu không tự quản lý? Tôi không nghĩ rằng đó là về sự pha trộn của các thành ngữ, nhiều hơn mà nhận được nhà nước theo cách này không thể tin tưởng. Tôi nghĩ rằng có một sự kiện miền ClusterState có thể được đăng ký với nó sẽ chính xác hơn (vì hệ thống sẽ tự nó gửi các trạng thái wholistic thông qua một người nghe) nhưng có thể chậm hơn so với phản ứng của phương thức trạng thái theo yêu cầu của nó trong bao lâu thay đổi. – jm0

4

Một cách tiếp cận có thể có diễn viên khác đăng ký vào ClusterDomainEvent bài viết, đặc biệt tìm kiếm các thành viên thông qua các sự kiện CurrentClusterState. Điều đó có thể trông giống như thế này:

case object GetMembers 

class ClusterMembersHolder extends Actor{ 
    var members:Set[Member] = Set() 
    override def preStart = { 
    val clusterSys = Cluster(context.system) 
    clusterSys.subscribe(self, classOf[ClusterDomainEvent]) 
    clusterSys.publishCurrentClusterState //Forces the current state 
    } 

    def receive = { 
    case state: CurrentClusterState => 
     members = state.members 

    case GetMembers => 
     sender ! members 
    } 
} 

Đây là loại một phác thảo thô (có thể cần một vài điều chỉnh), nhưng từ đây, bất kỳ diễn viên mà muốn biết danh sách thành viên hiện tại có thể gửi tin nhắn GetMembers này diễn viên qua ? và chờ phản hồi.

Phương pháp tiếp cận này giả định rằng bạn có thể có nhiều diễn viên muốn có thông tin này. Nếu nó chỉ ra rằng bạn chỉ có một diễn viên muốn thông tin này thì chỉ cần có diễn viên đăng ký vào sự kiện đó và cập nhật trạng thái nội bộ của nó với các thành viên.

+0

Diễn viên thuê bao, 'ClusterMemberHolder' cũng phải xử lý các sự kiện' MemberUp' và 'MemberRemoved'. publishCurrentClusterState là không cần thiết. –

8

Tweaked mẫu từ Typesafe Activator tutorial:

case object GetNodes 

class MemberListener extends Actor { 

    val cluster = Cluster(context.system) 

    override def preStart(): Unit = 
    cluster.subscribe(self, classOf[MemberEvent]) 

    override def postStop(): Unit = 
    cluster unsubscribe self 

    var nodes = Set.empty[Address] 

    def receive = { 
    case state: CurrentClusterState => 
     nodes = state.members.collect { 
     case m if m.status == MemberStatus.Up => m.address 
     } 
    case MemberUp(member) => 
     nodes += member.address 
    case MemberRemoved(member, _) => 
     nodes -= member.address 
    case _: MemberEvent ⇒ // ignore 
    case GetNodes => 
     sender ! nodes 
    } 
} 
Các vấn đề liên quan