• This repository has been archived on 15/Oct/2021
  • Stars
    star
    252
  • Rank 161,312 (Top 4 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created about 7 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An actor framework for Go

Go Report Card

gosiris is an actor framework for Golang.

Features

  • Manage a hierarchy of actors (each actor has its own: state, behavior, mailbox, child actors)
  • Deploy remote actors accessible though an AMQP broker or Kafka
  • Automated registration and runtime discoverability using etcd registry
  • Zipkin integration
  • Built-in patterns (become/unbecome, send, forward, repeat, child supervision)

Examples

Hello world

package main

import (
	"gosiris/gosiris"
)

func main() {
	//Init a local actor system
	gosiris.InitActorSystem(gosiris.SystemOptions{
		ActorSystemName: "ActorSystem",
	})

	//Create an actor
	parentActor := gosiris.Actor{}
	//Close an actor
	defer parentActor.Close()

	//Create an actor
	childActor := gosiris.Actor{}
	//Close an actor
	defer childActor.Close()
	//Register a reaction to event types ("message" in this case)
	childActor.React("message", func(context gosiris.Context) {
		context.Self.LogInfo(context, "Received %v\n", context.Data)
	})

	//Register an actor to the system
	gosiris.ActorSystem().RegisterActor("parentActor", &parentActor, nil)
	//Register an actor by spawning it
	gosiris.ActorSystem().SpawnActor(&parentActor, "childActor", &childActor, nil)

	//Retrieve actor references
	parentActorRef, _ := gosiris.ActorSystem().ActorOf("parentActor")
	childActorRef, _ := gosiris.ActorSystem().ActorOf("childActor")

	//Send a message from one actor to another (from parentActor to childActor)
	childActorRef.Tell(gosiris.EmptyContext, "message", "Hi! How are you?", parentActorRef)
}
INFO: [childActor] 1988/01/08 01:00:00 Received Hi! How are you?

Distributed actor system example

In the following example, in less than 30 effective lines of code, we will see how to create a distributed actor system implementing a request/reply interaction. An actor will be triggered by AMQP messages while another one will be triggered by Kafka events. Each actor will register itself in an etcd instance and will discover the other actor at runtime. Last but not least, gosiris will also manage the Zipkin integration by automatically managing the spans and forwarding the logs.

package main

import (
	"gosiris/gosiris"
	"time"
)

func main() {
	//Configure a distributed actor system with an etcd registry and a Zipkin integration
	gosiris.InitActorSystem(gosiris.SystemOptions{
		ActorSystemName: "ActorSystem",
		RegistryUrl:     "http://etcd:2379",
		ZipkinOptions: gosiris.ZipkinOptions{
			Url:      "http://zipkin:9411/api/v1/spans",
			Debug:    true,
			HostPort: "0.0.0.0",
			SameSpan: true,
		},
	})
	//Defer the actor system closure
	defer gosiris.CloseActorSystem()

	//Configure actor1
	actor1 := new(gosiris.Actor).React("reply", func(context gosiris.Context) {
		//Because Zipkin is enabled, the log will be also sent to the Zipkin server
		context.Self.LogInfo(context, "Received: %v", context.Data)

	})
	//Defer actor1 closure
	defer actor1.Close()
	//Register a remote actor accessible through AMQP
	gosiris.ActorSystem().RegisterActor("actor1", actor1, new(gosiris.ActorOptions).SetRemote(true).SetRemoteType(gosiris.Amqp).SetUrl("amqp://guest:guest@amqp:5672/").SetDestination("actor1"))

	//Configure actor2
	actor2 := new(gosiris.Actor).React("context", func(context gosiris.Context) {
		//Because Zipkin is enabled, the log will be also sent to the Zipkin server
		context.Self.LogInfo(context, "Received: %v", context.Data)
		context.Sender.Tell(context, "reply", "hello back", context.Self)
	})
	//Defer actor2 closure
	defer actor2.Close()
	//Register a remote actor accessible through Kafka
	gosiris.ActorSystem().SpawnActor(actor1, "actor2", actor2, new(gosiris.ActorOptions).SetRemote(true).SetRemoteType(gosiris.Kafka).SetUrl("kafka:9092").SetDestination("actor2"))

	//Retrieve the actor references
	actor1Ref, _ := gosiris.ActorSystem().ActorOf("actor1")
	actor2Ref, _ := gosiris.ActorSystem().ActorOf("actor2")

	//Send a message to the kafkaRef
	actor2Ref.Tell(gosiris.EmptyContext, "context", "hello", actor1Ref)

	time.Sleep(250 * time.Millisecond)
}
INFO: [actor2] 2017/11/11 00:38:24 Received: hello
INFO: [actor1] 2017/11/11 00:38:24 Received: hello back

More Examples

See the examples in actor_test.go.

Environment

First of all, to run the examples you must configure the following hostnames: etcd, amqp, zipkin, and kafka. Then to setup the full environment, you can simply run the Docker Compose.

Troubleshooting

You may experience errors during the tests like the following:

r.EncodeArrayStart undefined (type codec.encDriver has no field or method EncodeArrayStart)

This is a known issue with the etcd client used. The manual workaround (for the time being) is to delete manually the file keys.generated.go generated in /vendor.

Contributing

  • Open an issue if you want a new feature or if you spotted a bug
  • Feel free to propose pull requests

Any contribution is more than welcome! In the meantime, if we want to discuss gosiris you can contact me @teivah.

More Repositories

1

100-go-mistakes

📖 100 Go Mistakes and How to Avoid Them
Go
6,771
star
2

algodeck

An Open-Source Collection of 200+ Flash Cards to Help You Preparing Your Algorithms & Data Structures Interview 💯
5,600
star
3

sre-roadmap

An Opinionated Roadmap to Become an SRE (Concepts > Tools)
416
star
4

designdeck

An Open-Source Collection of 230+ Flash Cards to Help You Succeed in Your System Design Interview and More 💯
328
star
5

golang-good-code-bad-code

Go
160
star
6

broadcast

Notification broadcaster library
Go
152
star
7

gossip-glomers

My solutions to the Glomers Challenge: a series of distributed systems challenges.
Go
108
star
8

bitvector

Static bit vector structures library
Go
73
star
9

onecontext

Set of Go context's utilities.
Go
51
star
10

advent-of-code

🎄 My solutions to the Advents of Code, from 2015 to 2023 (450 🌟)
Go
50
star
11

go-lfu

A Go library for handling LFU cache operations in O(1)
Go
40
star
12

goptional

A lightweight library to provide a container for optional values in golang
Go
32
star
13

majorana

A RISC-V virtual processor, written in Go.
Go
22
star
14

ettore

A RISC-V virtual processor, written in Rust.
Rust
19
star
15

talks

My public talks
10
star
16

TIBreview

Quality code review for TIBCO BusinessWorks 6
Java
9
star
17

vertx-tutorial

Vert.x tutorial
Java
9
star
18

golang-parallel-mergesort

Go
8
star
19

tourniquet

gRPC client-side load balancer
Go
8
star
20

go-cpu-caches

Assembly
7
star
21

multilock

A Go Library to Efficiently Store a Set of Mutex or RWMutex
Go
7
star
22

disruptor-demo

Java
6
star
23

rust-cheatsheet

Rust Language Cheat Sheet
Rust
6
star
24

franz

A collection of Kafka utility tools (load testing, replication)
Rust
6
star
25

reactiveWM

A reactive framework for webMethods extending standard multithreading capabilties
Java
5
star
26

generics

A collection of Go generics utilities.
Go
5
star
27

spark-hdfs-helloworld

Java
5
star
28

resequencer

Resequencer library
Go
4
star
29

parallel-mergesort

Java
4
star
30

awesome-cs

A Curated List of Awesome Computer Science Resources
3
star
31

go-bbl

Brown Bag Lunch on the Go programming language
Go
2
star
32

flogomicroservice

Example of a Flogo microservice exposing a REST API
2
star
33

docker-hadoop

Dockerfile
2
star
34

teivah

1
star