DEV Community

Bikash Mishra
Bikash Mishra

Posted on

The Actor Model in Go: Simplifying Concurrent Programming

In the world of modern software development, concurrency is a necessity. With the rise of multi-core processors and distributed systems, applications need to be able to execute multiple tasks simultaneously to take full advantage of available hardware resources and ensure optimal performance.

One elegant solution to tackle concurrency is the Actor Model, a conceptual model for building concurrent and distributed systems. And now, with the power of Go, you can harness the benefits of this model with ease.

What is the Actor Model?

The Actor Model is a mathematical model of concurrent computation that treats actors as the universal primitives of concurrent computation. An actor is a lightweight, independent entity that operates concurrently and communicates with other actors by sending and receiving asynchronous messages.

In this model, each actor has its own mailbox, a queue where incoming messages are stored. The actor processes messages from its mailbox one by one, performing computations and potentially sending messages to other actors in response.

Introducing the Go Actor System

The Go Actor System is an implementation of the Actor Model in the Go programming language. It provides a framework for building concurrent applications using lightweight actors that communicate via message passing.

The Actor System consists of the following components:

  • Actor System Interface: The entry point for submitting tasks to the Actor System.
  • Task Queue: A queue that holds the tasks submitted by the Actor System Interface.
  • Assigner Actor: Responsible for reading tasks from the Task Queue and assigning them to available Actor instances.
  • Actors: Lightweight entities that execute the assigned tasks concurrently. Each Actor has its own Task Queue.
  • Auto Scaler: Dynamically increases or decreases the number of Actor instances based on the Task Queue size.

Using the Go Actor System

Using the Go Actor System is straightforward. Here's an example:

package main

import (
    "sync"
    "time"
    "github.com/forkbikash/aktor/actor"
    "github.com/forkbikash/aktor/actor_system"
    "github.com/forkbikash/aktor/entities"
)

type task struct{}

func (t *task) Execute() {}

func taskFunc() entities.Task {
    return &task{}
}

func main() {
    actorSystem := actor_system.CreateActorSystem("actor_system", &actor.Config{
        MinActor: 10,
        MaxActor: 100,
        AutoScale: actor.AutoScale{
            UpscaleQueueSize: 100,
            DownscaleQueueSize: 10,
        },
    })

    for i := 0; i < 1000; i += 1 {
        actorSystem.SubmitTask(taskFunc())
        <-time.After(2 * time.Millisecond)
    }

    systems := []*actor_system.ActorSystem{actorSystem}
    wg := &sync.WaitGroup{}
    wg.Add(len(systems))

    for _, system := range systems {
        go system.Shutdown(wg)
    }

    wg.Wait()
}
Enter fullscreen mode Exit fullscreen mode

In this example, we create an Actor System with a minimum of 10 and a maximum of 100 actors. We then submit 1000 tasks to the system, with a short delay between each submission. Finally, we shut down the system and wait for all tasks to complete.

What's Next?

The Go Actor System is a powerful tool for building concurrent applications, but there's always room for improvement. Some potential future enhancements include:

  • Assigning task IDs to each task and providing functionality to wait for the completion of a specific task.
  • Support for distributed environments, allowing actors to communicate across multiple machines.

With the Actor Model and the Go Actor System, concurrent programming becomes more accessible and manageable. Embrace the power of concurrency and take your applications to new heights with this elegant and efficient approach.

I hope this article helps someone out there.

If you liked the post, you can find more by:

Tweet this post
Follow me on Twitter @forkbikash

Top comments (0)