package actor_test import ( "context" "fmt" "time" "github.com/lightningnetwork/lnd/actor" "github.com/lightningnetwork/lnd/fn/v2" ) // RouterGreetingMsg is a message type for the router example. type RouterGreetingMsg struct { actor.BaseMessage Name string } // MessageType implements actor.Message. func (m RouterGreetingMsg) MessageType() string { return "RouterGreetingMsg" } // RouterGreetingResponse is a response type for the router example. type RouterGreetingResponse struct { Greeting string HandlerID string } // ExampleRouter demonstrates creating multiple actors under the same service // key and using a router to dispatch messages to them. func ExampleRouter() { system := actor.NewActorSystem() defer system.Shutdown() //nolint:ll routerGreeterKey := actor.NewServiceKey[RouterGreetingMsg, RouterGreetingResponse]( "router-greeter-service", ) // Behavior for the first greeter actor. actorID1 := "router-greeter-1" greeterBehavior1 := actor.NewFunctionBehavior( func(ctx context.Context, msg RouterGreetingMsg) fn.Result[RouterGreetingResponse] { return fn.Ok(RouterGreetingResponse{ Greeting: "Greetings, " + msg.Name + "!", HandlerID: actorID1, }) }, ) _, err := routerGreeterKey.Spawn(system, actorID1, greeterBehavior1) if err != nil { fmt.Printf("Failed to spawn actor: %v\n", err) return } fmt.Printf("Actor %s spawned.\n", actorID1) // Behavior for the second greeter actor. actorID2 := "router-greeter-2" greeterBehavior2 := actor.NewFunctionBehavior( func(ctx context.Context, msg RouterGreetingMsg) fn.Result[RouterGreetingResponse] { return fn.Ok(RouterGreetingResponse{ Greeting: "Salutations, " + msg.Name + "!", HandlerID: actorID2, }) }, ) _, err = routerGreeterKey.Spawn(system, actorID2, greeterBehavior2) if err != nil { fmt.Printf("Failed to spawn actor: %v\n", err) return } fmt.Printf("Actor %s spawned.\n", actorID2) // Create a router for the "router-greeter-service". greeterRouter := actor.NewRouter( system.Receptionist(), routerGreeterKey, actor.NewRoundRobinStrategy[RouterGreetingMsg, RouterGreetingResponse](), system.DeadLetters(), ) fmt.Printf("Router %s created for service key '%s'.\n", greeterRouter.ID(), "router-greeter-service") // Send messages through the router. names := []string{"Alice", "Bob", "Charlie", "David"} for _, name := range names { askCtx, askCancel := context.WithTimeout( context.Background(), 1*time.Second, ) futureResponse := greeterRouter.Ask( askCtx, RouterGreetingMsg{Name: name}, ) awaitCtx, awaitCancel := context.WithTimeout( context.Background(), 1*time.Second, ) result := futureResponse.Await(awaitCtx) result.WhenErr(func(err error) { fmt.Printf("For %s: Error - %v\n", name, err) }) result.WhenOk(func(response RouterGreetingResponse) { fmt.Printf("For %s: Received '%s' from %s\n", name, response.Greeting, response.HandlerID) }) awaitCancel() askCancel() } // Output: // Actor router-greeter-1 spawned. // Actor router-greeter-2 spawned. // Router router(router-greeter-service) created for service key 'router-greeter-service'. // For Alice: Received 'Greetings, Alice!' from router-greeter-1 // For Bob: Received 'Salutations, Bob!' from router-greeter-2 // For Charlie: Received 'Greetings, Charlie!' from router-greeter-1 // For David: Received 'Salutations, David!' from router-greeter-2 }