/ actor / example_basic_actor_test.go
example_basic_actor_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  // BasicGreetingMsg is a simple message type for the basic actor example.
 13  type BasicGreetingMsg struct {
 14  	actor.BaseMessage
 15  	Name string
 16  }
 17  
 18  // MessageType implements actor.Message.
 19  func (m BasicGreetingMsg) MessageType() string { return "BasicGreetingMsg" }
 20  
 21  // BasicGreetingResponse is a simple response type.
 22  type BasicGreetingResponse struct {
 23  	Greeting string
 24  }
 25  
 26  // ExampleActor demonstrates creating a single actor, sending it a message
 27  // directly using Ask, and then unregistering and stopping it.
 28  func ExampleActor() {
 29  	system := actor.NewActorSystem()
 30  	defer system.Shutdown()
 31  
 32  	//nolint:ll
 33  	greeterKey := actor.NewServiceKey[BasicGreetingMsg, BasicGreetingResponse](
 34  		"basic-greeter",
 35  	)
 36  
 37  	actorID := "my-greeter"
 38  	greeterBehavior := actor.NewFunctionBehavior(
 39  		func(ctx context.Context,
 40  			msg BasicGreetingMsg) fn.Result[BasicGreetingResponse] {
 41  
 42  			return fn.Ok(BasicGreetingResponse{
 43  				Greeting: "Hello, " + msg.Name + " from " +
 44  					actorID,
 45  			})
 46  		},
 47  	)
 48  
 49  	// Spawn the actor. This registers it with the system and receptionist,
 50  	// and starts it. It returns an ActorRef.
 51  	greeterRef, err := greeterKey.Spawn(system, actorID, greeterBehavior)
 52  	if err != nil {
 53  		fmt.Printf("Failed to spawn actor: %v\n", err)
 54  		return
 55  	}
 56  	fmt.Printf("Actor %s spawned.\n", greeterRef.ID())
 57  
 58  	// Send a message directly to the actor's reference.
 59  	askCtx, askCancel := context.WithTimeout(
 60  		context.Background(), 1*time.Second,
 61  	)
 62  	defer askCancel()
 63  	futureResponse := greeterRef.Ask(
 64  		askCtx, BasicGreetingMsg{Name: "World"},
 65  	)
 66  
 67  	awaitCtx, awaitCancel := context.WithTimeout(
 68  		context.Background(), 1*time.Second,
 69  	)
 70  	defer awaitCancel()
 71  	result := futureResponse.Await(awaitCtx)
 72  
 73  	result.WhenErr(func(err error) {
 74  		fmt.Printf("Error awaiting response: %v\n", err)
 75  	})
 76  	result.WhenOk(func(response BasicGreetingResponse) {
 77  		fmt.Printf("Received: %s\n", response.Greeting)
 78  	})
 79  
 80  	// Unregister the actor. This also stops the actor.
 81  	unregistered := greeterKey.Unregister(system, greeterRef)
 82  	if unregistered {
 83  		fmt.Printf("Actor %s unregistered and stopped.\n",
 84  			greeterRef.ID())
 85  	} else {
 86  		fmt.Printf("Failed to unregister actor %s.\n", greeterRef.ID())
 87  	}
 88  
 89  	// Verify it's no longer in the receptionist.
 90  	refsAfterUnregister := actor.FindInReceptionist(
 91  		system.Receptionist(), greeterKey,
 92  	)
 93  	fmt.Printf("Actors for key '%s' after unregister: %d\n",
 94  		"basic-greeter", len(refsAfterUnregister))
 95  
 96  	// Output:
 97  	// Actor my-greeter spawned.
 98  	// Received: Hello, World from my-greeter
 99  	// Actor my-greeter unregistered and stopped.
100  	// Actors for key 'basic-greeter' after unregister: 0
101  }