gam

package module
v0.0.0-...-c626584 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2016 License: Apache-2.0 Imports: 6 Imported by: 0

README

Go Actor Model

GAM is a MVP port of JVM Akka.Actor to Go.
This is mostly a learning experiment for me and not a production ready library.
Having spent way too much time in the Akka source code by starting the Akka.NET (Akka on .NET) project late 2013 I thought it could be a nice way to learn Go by porting the core of Akka.

Design philosophy:

  • Do one thing only, Actors
  • Networking and Clustering should be solved using adapters over other tools, e.g. gRPC and Consul
  • Serialization should be an external concern, GAM infrastructure and primitives should not be serialized

Hello world

type Hello struct{ Who string }
type HelloActor struct{}

func (state *HelloActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {
	case Hello:
		fmt.Printf("Hello %v\n", msg.Who)
	}
}

func NewHelloActor() gam.Actor {
	return &HelloActor{}
}

func main() {
	actor := gam.ActorOf(actor.Props(NewHelloActor))
	actor.Tell(Hello{Who: "Roger"})

  ...
}

State machines / Become and Unbecome

type Become struct {}
type Hello struct{ Who string }
type BecomeActor struct{}

func (state *BecomeActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {
	case Hello:
		fmt.Printf("Hello %v\n", msg.Who)
        context.Become(state.Other)
	}
}

func (state *BecomeActor) Other(context gam.Context) {
	switch msg := context.Message().(type) {
	case Hello:
		fmt.Printf("%v, ey we are now handling messages in another behavior",msg.Who)
	}
}

func NewBecomeActor() gam.Actor {
	return &BecomeActor{}
}

func main() {
	actor := gam.ActorOf(actor.Props(NewBecomeActor))
	actor.Tell(Hello{Who: "Roger"})
    actor.Tell(Hello{Who: "Roger"})
  
  ...  
}

Lifecycle events

Unlike Akka, GAM uses messages for lifecycle events instead of OOP method overrides

type Hello struct{ Who string }
type HelloActor struct{}

func (state *HelloActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {
	case gam.Started:
		fmt.Println("Started, initialize actor here")
	case gam.Stopping:
		fmt.Println("Stopping, actor is about shut down")
	case gam.Stopped:
		fmt.Println("Stopped, actor and it's children are stopped")
	case gam.Restarting:
		fmt.Println("Restarting, actor is about restart")
	case Hello:
		fmt.Printf("Hello %v\n", msg.Who)
	}
}

func NewHelloActor() gam.Actor {
	return &HelloActor{}
}

func main() {
	actor := gam.ActorOf(actor.Props(NewHelloActor))
	actor.Tell(Hello{Who: "Roger"})
    
    //why wait? 
    //Stop is a system message and is not processed through the user message mailbox
    //thus, it will be handled _before_ any user message
	time.Sleep(1 * time.Second)
	actor.Stop()

  ...
}

Supervision

Root actors are supervised by the actor.DefaultSupervisionStrategy(), which always issues a actor.RestartDirective for failing actors

type Hello struct{ Who string }
type HelloActor struct{}

func (state *HelloActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {
	case gam.Started:
		fmt.Println("Starting, initialize actor here")
	case gam.Restarting:
		fmt.Println("Restarting, actor is about restart")
	case Hello:
		fmt.Printf("Hello %v\n", msg.Who)
        panic("Ouch")
	}
}

func NewHelloActor() gam.Actor {
	return &HelloActor{}
}

func main() {
	actor := gam.ActorOf(actor.Props(NewHelloActor))
	actor.Tell(Hello{Who: "Roger"})
	
  ...
}

Child actors are supervised by their parents. Parents can customize their child supervisor strategy using gam.Props

decider := func(child gam.ActorRef, reason interface{}) gam.Directive {
	fmt.Println("handling failure for child")
	return gam.StopDirective
}
supervisor := gam.NewOneForOneStrategy(10,1000,decider)
actor := gam.ActorOf(gam.Props(NewParentActor).WithSupervisor(supervisor))

Example

type Hello struct{ Who string }
type ParentActor struct{}

func (state *ParentActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {	
	case Hello:
		child := context.ActorOf(gam.Props(NewChildActor))
		child.Tell(msg)
	}
}

func NewParentActor() gam.Actor {
	return &ParentActor{}
}

type ChildActor struct{}

func (state *ChildActor) Receive(context gam.Context) {
	switch msg := context.Message().(type) {
	case gam.Started:
		fmt.Println("Starting, initialize actor here")
	case gam.Stopping:
		fmt.Println("Stopping, actor is about shut down")
	case gam.Stopped:
		fmt.Println("Stopped, actor and it's children are stopped")
	case gam.Restarting:
		fmt.Println("Restarting, actor is about restart")
	case Hello:
		fmt.Printf("Hello %v\n", msg.Who)
        panic("Ouch")
	}
}

func NewChildActor() gam.Actor {
	return &ChildActor{}
}

func main() {
	decider := func(child gam.ActorRef, reason interface{}) gam.Directive {
		fmt.Println("handling failure for child")
		return gam.StopDirective
	}
	supervisor := gam.NewOneForOneStrategy(10,1000,decider)
	actor := gam.ActorOf(gam.Props(NewParentActor).WithSupervisor(supervisor))
	actor.Tell(Hello{Who: "Roger"})
	
	...
}

Documentation

Index

Constants

View Source
const (
	MailboxIdle    = iota
	MailboxRunning = iota
)
View Source
const (
	MailboxHasNoMessages   = iota
	MailboxHasMoreMessages = iota
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Actor

type Actor interface {
	Receive(message Context)
}

type ActorCell

type ActorCell struct {
	// contains filtered or unexported fields
}

func NewActorCell

func NewActorCell(props Properties, parent ActorRef) *ActorCell

func (*ActorCell) ActorOf

func (cell *ActorCell) ActorOf(props Properties) ActorRef

func (*ActorCell) Become

func (cell *ActorCell) Become(behavior Receive)

func (*ActorCell) BecomeStacked

func (cell *ActorCell) BecomeStacked(behavior Receive)

func (*ActorCell) Children

func (cell *ActorCell) Children() []ActorRef

func (*ActorCell) Parent

func (cell *ActorCell) Parent() ActorRef

func (*ActorCell) Self

func (cell *ActorCell) Self() ActorRef

func (*ActorCell) UnbecomeStacked

func (cell *ActorCell) UnbecomeStacked()

func (*ActorCell) Unwatch

func (cell *ActorCell) Unwatch(who ActorRef)

func (*ActorCell) Watch

func (cell *ActorCell) Watch(who ActorRef)

type ActorProducer

type ActorProducer func() Actor

type ActorRef

type ActorRef interface {
	Tell(message interface{})
	SendSystemMessage(message SystemMessage)
	Stop()
}

func ActorOf

func ActorOf(props Properties) ActorRef

type BoundedMailbox

type BoundedMailbox struct {
	// contains filtered or unexported fields
}

func (*BoundedMailbox) PostSystemMessage

func (mailbox *BoundedMailbox) PostSystemMessage(message SystemMessage)

func (*BoundedMailbox) PostUserMessage

func (mailbox *BoundedMailbox) PostUserMessage(message interface{})

func (*BoundedMailbox) RegisterHandlers

func (mailbox *BoundedMailbox) RegisterHandlers(userInvoke func(interface{}), systemInvoke func(SystemMessage))

func (*BoundedMailbox) Resume

func (mailbox *BoundedMailbox) Resume()

func (*BoundedMailbox) Suspend

func (mailbox *BoundedMailbox) Suspend()

type Context

type Context interface {
	Watch(ActorRef)
	Unwatch(ActorRef)
	Message() interface{}
	Become(Receive)
	BecomeStacked(Receive)
	UnbecomeStacked()
	Self() ActorRef
	Parent() ActorRef
	ActorOf(Properties) ActorRef
	Children() []ActorRef
}

func NewContext

func NewContext(cell *ActorCell, message interface{}) Context

type ContextValue

type ContextValue struct {
	*ActorCell
	// contains filtered or unexported fields
}

func (*ContextValue) Message

func (context *ContextValue) Message() interface{}

type Decider

type Decider func(child ActorRef, cause interface{}) Directive

type Directive

type Directive int
const (
	ResumeDirective Directive = iota
	RestartDirective
	StopDirective
	EscalateDirective
)

func DefaultDecider

func DefaultDecider(child ActorRef, reason interface{}) Directive

type Failure

type Failure struct {
	Who    ActorRef
	Reason interface{}
}

func (*Failure) SystemMessage

func (*Failure) SystemMessage()

type FutureActorRef

type FutureActorRef struct {
	// contains filtered or unexported fields
}

func NewFutureActorRef

func NewFutureActorRef() *FutureActorRef

func (*FutureActorRef) Result

func (ref *FutureActorRef) Result() interface{}

func (*FutureActorRef) ResultChannel

func (ref *FutureActorRef) ResultChannel() <-chan interface{}

func (*FutureActorRef) ResultOrTimeout

func (ref *FutureActorRef) ResultOrTimeout(timeout time.Duration) (interface{}, error)

func (*FutureActorRef) SendSystemMessage

func (ref *FutureActorRef) SendSystemMessage(message SystemMessage)

func (*FutureActorRef) Stop

func (ref *FutureActorRef) Stop()

func (*FutureActorRef) Tell

func (ref *FutureActorRef) Tell(message interface{})

type LocalActorRef

type LocalActorRef struct {
	// contains filtered or unexported fields
}

func NewLocalActorRef

func NewLocalActorRef(mailbox Mailbox) *LocalActorRef

func (*LocalActorRef) Resume

func (ref *LocalActorRef) Resume()

func (*LocalActorRef) SendSystemMessage

func (ref *LocalActorRef) SendSystemMessage(message SystemMessage)

func (*LocalActorRef) Stop

func (ref *LocalActorRef) Stop()

func (*LocalActorRef) Suspend

func (ref *LocalActorRef) Suspend()

func (*LocalActorRef) Tell

func (ref *LocalActorRef) Tell(message interface{})

type Mailbox

type Mailbox interface {
	PostUserMessage(message interface{})
	PostSystemMessage(message SystemMessage)
	Suspend()
	Resume()
	RegisterHandlers(userInvoke func(interface{}), systemInvoke func(SystemMessage))
}

func NewBoundedMailbox

func NewBoundedMailbox(boundedSize int) Mailbox

func NewUnboundedMailbox

func NewUnboundedMailbox() Mailbox

type MailboxProducer

type MailboxProducer func(func(interface{}), func(SystemMessage)) Mailbox

type OneForOneStrategy

type OneForOneStrategy struct {
	// contains filtered or unexported fields
}

func (*OneForOneStrategy) Handle

func (strategy *OneForOneStrategy) Handle(child ActorRef, reason interface{}) Directive

type OtherStopped

type OtherStopped struct {
	Who ActorRef
}

func (*OtherStopped) SystemMessage

func (*OtherStopped) SystemMessage()

type PoisonPill

type PoisonPill struct{}

type Properties

type Properties interface {
	ProduceActor() Actor
	Mailbox() Mailbox
	Supervisor() SupervisionStrategy
}

type PropsValue

type PropsValue struct {
	// contains filtered or unexported fields
}

func Props

func Props(actorProducer ActorProducer) PropsValue

func (PropsValue) Mailbox

func (props PropsValue) Mailbox() Mailbox

func (PropsValue) ProduceActor

func (props PropsValue) ProduceActor() Actor

func (PropsValue) Supervisor

func (props PropsValue) Supervisor() SupervisionStrategy

func (PropsValue) WithMailbox

func (props PropsValue) WithMailbox(mailbox Mailbox) PropsValue

func (PropsValue) WithSupervisor

func (props PropsValue) WithSupervisor(supervisor SupervisionStrategy) PropsValue

type Receive

type Receive func(Context)

type Restart

type Restart struct{}

func (*Restart) SystemMessage

func (*Restart) SystemMessage()

type Restarting

type Restarting struct{}

user message

type Resume

type Resume struct{}

func (*Resume) SystemMessage

func (*Resume) SystemMessage()

type Started

type Started struct{}

type Stop

type Stop struct{}

func (*Stop) SystemMessage

func (*Stop) SystemMessage()

type Stopped

type Stopped struct{}

type Stopping

type Stopping struct{}

type SupervisionStrategy

type SupervisionStrategy interface {
	Handle(child ActorRef, cause interface{}) Directive
}

func DefaultSupervisionStrategy

func DefaultSupervisionStrategy() SupervisionStrategy

func NewOneForOneStrategy

func NewOneForOneStrategy(maxNrOfRetries int, withinTimeRangeMilliseconds int, decider Decider) SupervisionStrategy

type SystemMessage

type SystemMessage interface {
	SystemMessage()
}

type UnboundedMailbox

type UnboundedMailbox struct {
	// contains filtered or unexported fields
}

func (*UnboundedMailbox) PostSystemMessage

func (mailbox *UnboundedMailbox) PostSystemMessage(message SystemMessage)

func (*UnboundedMailbox) PostUserMessage

func (mailbox *UnboundedMailbox) PostUserMessage(message interface{})

func (*UnboundedMailbox) RegisterHandlers

func (mailbox *UnboundedMailbox) RegisterHandlers(userInvoke func(interface{}), systemInvoke func(SystemMessage))

func (*UnboundedMailbox) Resume

func (mailbox *UnboundedMailbox) Resume()

func (*UnboundedMailbox) Suspend

func (mailbox *UnboundedMailbox) Suspend()

type Unwatch

type Unwatch struct {
	Watcher ActorRef
}

func (*Unwatch) SystemMessage

func (*Unwatch) SystemMessage()

type Watch

type Watch struct {
	Watcher ActorRef
}

func (*Watch) SystemMessage

func (*Watch) SystemMessage()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL