github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/clusterproviders/automanaged/member_list_broadcast_test.go (about)

     1  package automanaged
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/asynkron/protoactor-go/cluster/identitylookup/disthash"
     8  
     9  	"github.com/asynkron/protoactor-go/actor"
    10  	"github.com/asynkron/protoactor-go/cluster"
    11  	"github.com/asynkron/protoactor-go/remote"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestMemberList_Broadcast(t *testing.T) {
    16  	c := startNode()
    17  	defer c.Shutdown(true)
    18  
    19  	var receivedEvent *cluster.GrainRequest
    20  
    21  	for i := 1; i < 20; i++ { // retry several times as we don't know when the cluster will be ready
    22  		var ok bool
    23  		if receivedEvent, ok = trySendAndReceiveMessage(t, c, 0xBEEF); ok {
    24  			break
    25  		}
    26  	}
    27  
    28  	assert.Equal(t, int32(0xBEEF), receivedEvent.MethodIndex)
    29  }
    30  
    31  func startNode() *cluster.Cluster {
    32  	system := actor.NewActorSystem()
    33  
    34  	provider := New()
    35  	config := remote.Configure("localhost", 0)
    36  
    37  	lookup := disthash.New()
    38  	clusterConfig := cluster.Configure("my-cluster", provider, lookup, config)
    39  	cluster := cluster.New(system, clusterConfig)
    40  
    41  	cluster.StartMember()
    42  
    43  	return cluster
    44  }
    45  
    46  func subscribe(c *cluster.Cluster) (events <-chan *cluster.GrainRequest, cancel func()) {
    47  	eventChan := make(chan *cluster.GrainRequest, 1)
    48  
    49  	subscription := c.ActorSystem.EventStream.Subscribe(func(evt interface{}) {
    50  		if event, ok := evt.(*cluster.GrainRequest); ok {
    51  			eventChan <- event
    52  		}
    53  	})
    54  
    55  	return eventChan, func() { c.ActorSystem.EventStream.Unsubscribe(subscription) }
    56  }
    57  
    58  func trySendAndReceiveMessage(t *testing.T, c *cluster.Cluster, methodIndex int32) (receivedEvent *cluster.GrainRequest, ok bool) {
    59  	events, cancel := subscribe(c)
    60  
    61  	time.Sleep(500 * time.Millisecond)
    62  
    63  	c.MemberList.BroadcastEvent(&cluster.GrainRequest{MethodIndex: methodIndex}, true)
    64  
    65  	select {
    66  	case receivedEvent = <-events:
    67  		ok = true
    68  	case <-time.After(1 * time.Second):
    69  		t.Error("Timed out waiting for the event to arrive")
    70  	}
    71  
    72  	cancel()
    73  
    74  	return
    75  }