Go Version License Factorio Concurrency Architecture
This repository demonstrates a concurrency-oriented data flow pattern in Go inspired by the Main Bus concept from the game Factorio.
In Factorio, a Main Bus is a corridor of parallel belts dedicated to a single resource (iron plates, copper plates, steel, etc.). Each resource has its own bus, and each bus is made of multiple parallel belts (preferably an even number) to ensure symmetry and expansion.
We translate that concept to software:
- Each belt becomes a Go channel.
- Each Main Bus is a set of parallel channels dedicated to a single resource type.
- Multiple independent Main Buses can coexist and scale separately.
- Predictable, scalable flows per resource
- Separation of concerns: one bus per resource
- Easy horizontal scaling by adding more conveyors (channels)
- Independent consumers per conveyor to avoid contention across buses
Conveyoris achan Event(a single belt)MainBusgroups multiple conveyors for a single resource- Producers push events onto a random conveyor within the bus
- Consumers read from conveyors independently (one goroutine per conveyor)
The core types are in main.go:
Eventcarries an ID, resource name, value (payload), and timestampConveyoris an alias forchan EventMainBusholds the resource name and slice of conveyorsNewMainBus(resource, lines, buffer)creates a bus with an even number of conveyorsProduce(ev)pushes an event to a random conveyorConsume(line, wg)reads from a single conveyor until closedClose()shuts down all conveyors in the bus
Run the example:
go run .What it does:
- Creates two independent buses:
iron(4 conveyors) andcopper(2 conveyors) - Starts one consumer goroutine per conveyor
- Produces 10 events for each bus, distributing them across conveyors
- Closes the buses and waits for all consumers to finish
Example output (truncated):
[Consumer-iron-L0] ID:0 Value:Iron Plate Time:12:34:56
[Consumer-copper-L1] ID:1 Value:Copper Plate Time:12:34:56
...
All main buses completed processing.
- Even number of conveyors is enforced (if an odd number is passed, one is added) to mirror Factorio conventions and maintain balanced parallelism.
- Random distribution simulates simple load-balancing across conveyors. You can replace it with other strategies (round-robin, hashing by event ID, etc.).
- Each bus is independent. Adding a new resource means creating a new
MainBuswith its own set of conveyors.
- Add metrics for per-conveyor throughput and backpressure
- Implement different balancing strategies (round-robin, consistent hashing)
- Add backpressure signals or context cancellation for graceful shutdowns
- Introduce typed payloads using generics (Go 1.18+) if needed
đ§Š MAIN BUS ARCHITECTURE (inspired by Factorio)
âââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââ
â PRODUCERS â â CONSUMERS â
âââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââ
â â
â â
âź âź
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
MAIN BUS COMPLEX (each bus dedicated to a single resource)
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â IRON BUS â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 1 âââââââââśâ Conveyor 0 âââââââââśâ Consumer 0 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 2 âââââââââśâ Conveyor 1 âââââââââśâ Consumer 1 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 3 âââââââââśâ Conveyor 2 âââââââââśâ Consumer 2 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 4 âââââââââśâ Conveyor 3 âââââââââśâ Consumer 3 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â˛ăăăă â˛ăăăă â˛ăăăă â˛ăăăă
â â â â
â â â â
âââââââ Parallel channels (chan Event) âââââââââ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â COPPER BUS â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 1 âââââââââśâ Conveyor 0 âââââââââśâ Consumer 0 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
â â Producer 2 âââââââââśâ Conveyor 1 âââââââââśâ Consumer 1 â â
â ââââââââââââââ ââââââââââââââ ââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
SYSTEM BEHAVIOR
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
- Each MainBus handles one type of resource (e.g., iron, copper, steel)
- Each bus contains multiple conveyors (channels) for parallel throughput
- Producers send Events to a random conveyor in their bus
- Consumers independently drain events from their assigned conveyor
- Buses operate concurrently and independently
- Adding a new resource = adding a new MainBus (no refactor needed)
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
LEGEND
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
âś Flow direction of data (Event)
â Connection between components
â Conveyor (chan Event)
â Structural separation / conceptual grouping
đ§Š MAIN BUS SYSTEM - UML ASCII
ââââââââââââââââââââââââââââââ
â Event â
âââââââââââââââââââââââââââââ
â + ID: int â
â + Resource: string â
â + Value: any â
â + Time: time.Time â
ââââââââââââââââââââââââââââââ
ââââââââââââââââââââââââââââââ
â Conveyor â
âââââââââââââââââââââââââââââ
â type Conveyor chan Event â
ââââââââââââââââââââââââââââââ
ââââââââââââââââââââââââââââââ
â MainBus â
âââââââââââââââââââââââââââââ
â - Resource: string â
â - Conveyors: []Conveyor â
âââââââââââââââââââââââââââââ
â + Produce(ev Event) â
â + Consume(line int, wg*) â
â + Close() â
ââââââââââââââââââââââââââââââ
â˛ăăăă
â 1..*
â Contains
â
ââââââââââââââââââââââââââââââ
â Conveyor[0..N] â
ââââââââââââââââââââââââââââââ
ââââââââââââââââââââââââââââââ
â Producer â
âââââââââââââââââââââââââââââ
â + Produce(ev Event, bus*) â
ââââââââââââââââââââââââââââââ
â
â sends Event
âź
ââââââââââââââââââââââââââââââ
â MainBus â
ââââââââââââââââââââââââââââââ
â
â distributes Event to random Conveyor
âź
ââââââââââââââââââââââââââââââ
â Consumer â
âââââââââââââââââââââââââââââ
â + Consume(Conveyor) â
ââââââââââââââââââââââââââââââ
- Producer creates Events and sends them to the MainBus.
- MainBus distributes events across its Conveyors (parallel channels).
- Each Consumer drains from a specific Conveyor.
- Each resource has its own independent MainBus.
- The system is modular, scalable, and concurrent, enabling expansion without refactors.
- Go 1.20+
MIT