Coder Social home page Coder Social logo

goactor's Introduction

GoActor

A tree-based actor framework implementation for Golang.

Inspired by

this is my attempt to leverage Go's simple concurrency and channel-based messaging.

Description

The two primary entities in this package are the Actor interface and Base struct. Base implements Actor, and needs only be embedded in a user's structs to make them actors. To be active, i.e. to be able to process messages, the actors themselves need to first be 'spawned' either by the main application or by other actors. This spawning process returns an Inbox, a kind of mailbox for an actor to receive messages. Two public messages are provided in this package:

Message Description
SendStopMsg(Inbox) Requests the actor identified by Inbox to stop.
SendErrorMsg(Inbox, error) Reports an error to the actor identified by Inbox.

Every spawned actor sequentially processes the received messages in First-In-First-Out order. Therefore, mutexes are not necessary.

The main application spawns an actor via SpawnRoot function. Such an actor is a Root actor. Any actor can launch another actor via receiver method SpawnNested. In this case, the former is the creator actor; and the latter is the nested actor.

Tree-based messaging

Built with simplicity in mind, an actor can normally communicate with only its creator and nested actors it creates. The main application always launches the Root actor, from which the tree proliferates.

graph TD
    main[main.go] --> |SpawnRoot| actorA[ActorA]
    actorA --> |SpawnNested| actorB[ActorB]
    actorA --> |SpawnNested| actorC[ActorC]
    actorC --> |SpawnNested| actorD[ActorD]
    actorC --> |SpawnNested| actorE[ActorE]
Loading

Messages inbound to an actor are generally defined along with the actor. Messages outbound to a creator, i.e. events, are done via interfaces. This leaves the creator actor to handle the events (implement the interfaces) as desired.

Error and stop propogation are two things done very easily with this kind of messaging. By default, an error encountered by a nested actor leads to the termination of the actor, and propogation of the error up the tree until the whole tree stops. This default behavior can be overridden as noted in the Actor API table below.

Sample main.go implementation

The snippet below is complete in itself, even though the actor doesn't do anything more than being launched.

package main

import (
    "fmt"
	"os"
	"os/signal"
	"syscall"

	actor "gitlab.com/prithvivishak/goactor"
)

type MyActor struct {
    actor.Base
    // Other fields here.
}

func main() {
	osSignal := make(chan os.Signal)
	signal.Notify(osSignal, os.Interrupt, syscall.SIGTERM)

	myactor := new(MyActor) // Initialize however you see fit.
	rootDone, rootInbox, err := actor.SpawnRoot(myactor, "SomeIDHere")
	if err != nil {
		fmt.Println("FATAL: Could not launch the root actor.")
		os.Exit(1)
	}

	for {
		select {
		case <-rootDone:
			return
		case <-osSignal:
			actor.SendStopMsg(rootInbox) // Allow the actor to stop gracefully, which sends above done.
		}
	}
}

Actor API

Function Description
Inbox() Inbox Returns the mailbox of the actor. Useful for sending a message to self; e.g. from a spawned go routine or a time.AfterFunc timer.
CreatorInbox() Inbox Returns the mailbox of the actor's creator. Useful for sending messages up the tree hierarchy.
SpawnNested(Actor, string) (Inbox, error) Launches an actor as a nested actor, returning its mailbox for custom use.
Initialize() error Use this function to provide your own initialization steps, including spawning other go routines.
IsStopping() bool Returns true if the actor is in the process of stopping. Use for custom actor termination logic.
Finalize() Use this function to finalize whatever was done in Initialize(). This is guaranteed to run even if Initialize() errors out.
HandleError(error) error Override this function to provide your own error handling. Default is to propagate the error, hence stop.
HandleLastMsg(Actor, error) error Override this function to perform custom actions with the stopped nested actor, including re-spawning it.
ID() string Returns the string used to identify an actor upon launch. Useful in HandleLastMsg and debugging statements.

goactor's People

Contributors

vsatindriya avatar pippadi avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.