GitHub - vladopajic/go-actor: A lightweight library for writing concurrent programs in Go using the Actor model. (original) (raw)

go-actor

test lint coverage Go Report Card GoDoc Release

goactor-cover

go-actor is a lightweight library for writing concurrent programs in Go using the Actor model.

Motivation

Without reusable design principles, maintaining a complex codebase can be challenging, as developers implement logic differently when no common practice is defined.

go-actor aims to provide a pattern for building highly efficient programs, giving developers a straightforward approach to designing components, the building blocks of programs, using a pattern based on the Actor Model and Communicating Sequential Processes (CSP).

Advantage

Abstractions

The core abstraction layer of go-actor consists of three primary interfaces:

Examples

Explore the examples repository to see go-actor in action. Reviewing these examples is highly recommended, as they will greatly enhance your understanding of the library.

// This example will demonstrate how to create actors for producer-consumer use case. // Producer will create incremented number on every 1 second interval and // consumer will print whatever number it receives. func main() { mbx := actor.NewMailboxint

// Produce and consume workers are created with same mailbox
// so that produce worker can send messages directly to consume worker
p := actor.New(&producerWorker{mailbox: mbx})
c1 := actor.New(&consumerWorker{mailbox: mbx, id: 1})

// Note: Example creates two consumers for the sake of demonstration
// since having one or more consumers will produce the same result. 
// Message on stdout will be written by first consumer that reads from mailbox.
c2 := actor.New(&consumerWorker{mailbox: mbx, id: 2})

// Combine all actors to singe actor so we can start and stop all at once
a := actor.Combine(mbx, p, c1, c2).Build()
a.Start()
defer a.Stop()

// Stdout output:
// consumed 1      (worker 1)
// consumed 2      (worker 2)
// consumed 3      (worker 1)
// consumed 4      (worker 2)
// ...

select {}

}

// producerWorker will produce incremented number on 1 second interval type producerWorker struct { mailbox actor.MailboxSender[int] num int }

func (w *producerWorker) DoWork(ctx actor.Context) actor.WorkerStatus { select { case <-ctx.Done(): return actor.WorkerEnd

case <-time.After(time.Second):
    w.num++
    w.mailbox.Send(ctx, w.num)

    return actor.WorkerContinue
}

}

// consumerWorker will consume numbers received on mailbox type consumerWorker struct { mailbox actor.MailboxReceiver[int] id int }

func (w *consumerWorker) DoWork(ctx actor.Context) actor.WorkerStatus { select { case <-ctx.Done(): return actor.WorkerEnd

case num := <-w.mailbox.ReceiveC():
    fmt.Printf("consumed %d \t(worker %d)\n", num, w.id)

    return actor.WorkerContinue
}

}

Add-ons

While go-actor is designed to be a minimal library with lean interfaces, developers can extend its functionality with domain-specific add-ons. Some notable add-ons include:

Pro Tips

To enhance code quality in projects that heavily rely on the actor model with go-actor, consider adhering to best practices and reviewing common hurdles for frequently encountered issues.

Design Decisions

You can find detailed design decisions here.

Benchmarks

See library benchmarks here.

Versioning

The go-actor library adopts a versioning scheme structured as x.y.z.

Initially, the library will utilize the format 0.y.z as it undergoes refinement until it attains a level of stability where fundamental interfaces and core principles no longer necessitate significant alterations. Within this semantic, the y component signifies a version that is not backward-compatible. It is advisable for developers to review the release notes carefully to gain insight into these modifications. Furthermore, the final component, z, denotes releases incorporating changes that are backward-compatible.

Contribution

All contributions are useful, whether it is a simple typo, a more complex change, or just pointing out an issue. We welcome any contribution so feel free to open PR or issue.

Continue reading here.

Happy coding 🌞