/ actor / example_router_test.go
example_router_test.go
  1  package actor_test
  2  
  3  import (
  4  	"context"
  5  	"fmt"
  6  	"time"
  7  
  8  	"github.com/lightningnetwork/lnd/actor"
  9  	"github.com/lightningnetwork/lnd/fn/v2"
 10  )
 11  
 12  // RouterGreetingMsg is a message type for the router example.
 13  type RouterGreetingMsg struct {
 14  	actor.BaseMessage
 15  	Name string
 16  }
 17  
 18  // MessageType implements actor.Message.
 19  func (m RouterGreetingMsg) MessageType() string { return "RouterGreetingMsg" }
 20  
 21  // RouterGreetingResponse is a response type for the router example.
 22  type RouterGreetingResponse struct {
 23  	Greeting  string
 24  	HandlerID string
 25  }
 26  
 27  // ExampleRouter demonstrates creating multiple actors under the same service
 28  // key and using a router to dispatch messages to them.
 29  func ExampleRouter() {
 30  	system := actor.NewActorSystem()
 31  	defer system.Shutdown()
 32  
 33  	//nolint:ll
 34  	routerGreeterKey := actor.NewServiceKey[RouterGreetingMsg, RouterGreetingResponse](
 35  		"router-greeter-service",
 36  	)
 37  
 38  	// Behavior for the first greeter actor.
 39  	actorID1 := "router-greeter-1"
 40  	greeterBehavior1 := actor.NewFunctionBehavior(
 41  		func(ctx context.Context,
 42  			msg RouterGreetingMsg) fn.Result[RouterGreetingResponse] {
 43  
 44  			return fn.Ok(RouterGreetingResponse{
 45  				Greeting:  "Greetings, " + msg.Name + "!",
 46  				HandlerID: actorID1,
 47  			})
 48  		},
 49  	)
 50  	_, err := routerGreeterKey.Spawn(system, actorID1, greeterBehavior1)
 51  	if err != nil {
 52  		fmt.Printf("Failed to spawn actor: %v\n", err)
 53  		return
 54  	}
 55  	fmt.Printf("Actor %s spawned.\n", actorID1)
 56  
 57  	// Behavior for the second greeter actor.
 58  	actorID2 := "router-greeter-2"
 59  	greeterBehavior2 := actor.NewFunctionBehavior(
 60  		func(ctx context.Context,
 61  			msg RouterGreetingMsg) fn.Result[RouterGreetingResponse] {
 62  
 63  			return fn.Ok(RouterGreetingResponse{
 64  				Greeting:  "Salutations, " + msg.Name + "!",
 65  				HandlerID: actorID2,
 66  			})
 67  		},
 68  	)
 69  	_, err = routerGreeterKey.Spawn(system, actorID2, greeterBehavior2)
 70  	if err != nil {
 71  		fmt.Printf("Failed to spawn actor: %v\n", err)
 72  		return
 73  	}
 74  	fmt.Printf("Actor %s spawned.\n", actorID2)
 75  
 76  	// Create a router for the "router-greeter-service".
 77  	greeterRouter := actor.NewRouter(
 78  		system.Receptionist(), routerGreeterKey,
 79  		actor.NewRoundRobinStrategy[RouterGreetingMsg,
 80  			RouterGreetingResponse](),
 81  		system.DeadLetters(),
 82  	)
 83  	fmt.Printf("Router %s created for service key '%s'.\n",
 84  		greeterRouter.ID(), "router-greeter-service")
 85  
 86  	// Send messages through the router.
 87  	names := []string{"Alice", "Bob", "Charlie", "David"}
 88  	for _, name := range names {
 89  		askCtx, askCancel := context.WithTimeout(
 90  			context.Background(), 1*time.Second,
 91  		)
 92  		futureResponse := greeterRouter.Ask(
 93  			askCtx, RouterGreetingMsg{Name: name},
 94  		)
 95  
 96  		awaitCtx, awaitCancel := context.WithTimeout(
 97  			context.Background(), 1*time.Second,
 98  		)
 99  		result := futureResponse.Await(awaitCtx)
100  
101  		result.WhenErr(func(err error) {
102  			fmt.Printf("For %s: Error - %v\n", name, err)
103  		})
104  		result.WhenOk(func(response RouterGreetingResponse) {
105  			fmt.Printf("For %s: Received '%s' from %s\n",
106  				name, response.Greeting, response.HandlerID)
107  		})
108  		awaitCancel()
109  		askCancel()
110  	}
111  
112  	// Output:
113  	// Actor router-greeter-1 spawned.
114  	// Actor router-greeter-2 spawned.
115  	// Router router(router-greeter-service) created for service key 'router-greeter-service'.
116  	// For Alice: Received 'Greetings, Alice!' from router-greeter-1
117  	// For Bob: Received 'Salutations, Bob!' from router-greeter-2
118  	// For Charlie: Received 'Greetings, Charlie!' from router-greeter-1
119  	// For David: Received 'Salutations, David!' from router-greeter-2
120  }