🚀Get Started

  • Define the messages that you want the given actor should handle using Google Protocol Buffers.

  • Make use Buf or protoc to generate the go code.

  • Implement the Actorinterface to define the given actor.

Example

Messages definition

syntax = "proto3";

package hellopb;

message SayHello {}

message SayHi {}

Generate Code

We use Buf to generate the golang code. You can check the examples repo for more information

Actor Implementation

type HelloWorld struct{}

var _ actors.Actor = (*HelloWorld)(nil)

// NewHelloWorld creates an instance
func NewHelloWorld() *HelloWorld {
	return &HelloWorld{}
}

func (x *HelloWorld) PreStart(context.Context) error { return nil }

func (x *HelloWorld) Receive(ctx *actors.ReceiveContext) {
	switch ctx.Message().(type) {
	case *goaktpb.PostStart:
	case *hellopb.SayHello:
		// here the receiving actor is responding to the message
		ctx.Response(new(hellopb.SayHi))
	default:
		ctx.Unhandled()
	}
}

func (x *HelloWorld) PostStop(context.Context) error { return nil }

Complete Example


package main

import (
	"context"
	"os"
	"os/signal"
	"syscall"
	"time"

	goakt "github.com/tochemey/goakt/v3/actor"
	"github.com/tochemey/goakt/v3/log"

	hellopb "github.com/tochemey/goakt-examples/v2/internal/helloworldpb"
)

func main() {
	ctx := context.Background()

	// use the address default log. real-life implement the log interface`
	logger := log.DefaultLogger

	// create the actor system. kindly in real-life application handle the error
	actorSystem, _ := goakt.NewActorSystem(
		"HelloWorld",
		goakt.WithLogger(logger),
		goakt.WithPassivationDisabled(),
		goakt.WithActorInitMaxRetries(3))

	// start the actor system
	if err := actorSystem.Start(ctx); err != nil {
		logger.Fatal(err)
		os.Exit(1)
	}

	// create a Hello actor
	pid, err := actorSystem.Spawn(ctx, "Hello", NewHelloWorld())
	if err != nil {
		logger.Fatal(err)
		os.Exit(1)
	}

	// send an SayHello message to the actor and expect a response
	response, err := goakt.Ask(ctx, pid, new(hellopb.SayHello), time.Second)
	if err != nil {
		logger.Fatal(err)
		os.Exit(1)
	}

	switch response.(type) {
	case *hellopb.SayHi:
		logger.Info("received SayHi from actor")
	default:
		logger.Fatal("unexpected response from actor")
	}

	// capture ctrl+c
	interruptSignal := make(chan os.Signal, 1)
	signal.Notify(interruptSignal, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
	<-interruptSignal

	// stop the actor system
	_ = actorSystem.Stop(ctx)
	os.Exit(0)
}

type HelloWorld struct{}

var _ goakt.Actor = (*HelloWorld)(nil)

// NewHelloWorld creates an instance of HelloWorld Actor
func NewHelloWorld() *HelloWorld {
	return &HelloWorld{}
}

func (x *HelloWorld) PreStart(context.Context) error { return nil }

func (x *HelloWorld) Receive(ctx *goakt.ReceiveContext) {
	switch ctx.Message().(type) {
	case *hellopb.SayHello:
		ctx.Response(new(hellopb.SayHi))
	default:
		ctx.Unhandled()
	}
}

func (x *HelloWorld) PostStop(context.Context) error { return nil }

More Examples

See Examples

Last updated