This directory contains example programs demonstrating how to use the Akita simulation framework. They progress from minimal event scheduling to full component communication patterns.
The simplest Akita program. Creates an engine, registers an event handler, schedules one event, and runs the simulation.
Key concepts: timing.Engine, timing.Event, timing.Handler, event
scheduling.
cd 01_print_event && go run main.goSimulates cell splitting: each cell schedules two split events at random future times, creating exponential growth. Demonstrates dynamic event scheduling where handlers create new events during execution.
Key concepts: Custom event types, recursive event scheduling, random timing.
cd 02_cell_split && go run main.goA single tick-based component, no ports. Takes one ±1 step per cycle until it drifts to ±10 from the origin, then prints the final position, step count, and simulated time. Smallest useful Akita simulation.
Key concepts: modeling.Component, the
type Comp = modeling.Component[Spec, State, modeling.None] alias,
Spec/State separation, the Tick() bool middleware contract,
TickLater to start the loop, middleware holding auxiliary state (a seeded
RNG) outside Spec/State.
cd 03_random_walk && go run main.goTwo components exchange ping/pong messages using the ticking middleware
paradigm (modeling.Component[Spec, State, modeling.None]). Each component has
two middlewares:
- sendMW — Sends a
PingMsgeach tick untilNumPingPerCycleis reached. - receiveProcessMW — Receives incoming
PingMsgmessages from the port and sendsPongMsgresponses.
Key concepts: modeling.Component, Spec/State separation, middleware
pattern, port-based communication, builder pattern.
cd tickingping && go test -v -run ExampleTwo components exchange ping/pong messages using the event-driven
paradigm (modeling.EventDrivenComponent[Spec, State, modeling.None]). A single
PingProcessor handles all logic: sending scheduled pings, processing
incoming requests, and delivering responses after a configurable delay.
Key concepts: modeling.EventDrivenComponent, EventProcessor interface,
delayed response delivery, event-driven (non-ticking) design.
cd ping && go test -v -run ExampleTwo ticking agents exchange a ping/response, observed entirely from the
outside. An engine hook logs every event and a port hook logs every message;
the agents themselves print nothing. Shows the hooking API
(Hook, HookCtx, AcceptHook) and the engine/port hook positions.
Key concepts: hooking.Hook, HookCtx, AcceptHook,
timing.HookPosBeforeEvent, messaging.HookPosPortMsgSend/Recvd.
cd hooks && go run main.goA random walker defines its own HookPos and fires it with InvokeHook on
every step, exposing internal behavior the built-in hook points cannot see.
An external hook logs each step; the walker itself prints nothing.
Key concepts: declaring a hooking.HookPos, InvokeHook, a component as
Hookable, payload via HookCtx.Item.
cd customhook && go run main.goA single worker component wraps each job in a tracing task
(tracing.StartTask / EndTask). A BusyTimeTracer and an
AverageTimeTracer, attached with tracing.CollectTrace, report how long
the worker was busy and how long an average job took.
Key concepts: tracing tasks, tracing.CollectTrace, BusyTimeTracer,
AverageTimeTracer, TaskFilter — tracing built on hooks.
cd tracing && go run main.goA worker plus a hand-written maxDurationTracer that implements the
tracing.Tracer interface (real StartTask/EndTask, no-op
StepTask/AddMilestone) and reports the longest job. Attached the same way
as a built-in tracer, with tracing.CollectTrace.
Key concepts: the tracing.Tracer interface, holding state across
StartTask/EndTask, reading a timing.TimeTeller.
cd customtracer && go run main.goA client and server exchange request/response over a direct connection,
annotated with the four request helpers (TraceReqInitiate, TraceReqReceive,
TraceReqComplete, TraceReqFinalize). Two AverageTimeTracers — filtering
req_out and req_in — report round-trip latency and server handling time
from the same run.
Key concepts: nested req_out/req_in tasks, the four TraceReq*
helpers, selecting tasks by Kind with a TaskFilter.
cd reqtracing && go run main.goA request travels a memory hierarchy (Client → L1 → L2 → Memory); each cache
misses and forwards downward, parenting the downstream task to the one it is
handling with tracing.MsgIDAtReceiver. A custom tracer attached to every
component prints the resulting task tree.
Key concepts: tracing.MsgIDAtReceiver, parentID chaining, task trees
across components, attaching one tracer to many domains.
cd tasktree && go run main.go| Paradigm | Component Type | When to Use |
|---|---|---|
| Ticking | modeling.Component[S, T, R] |
Pipeline-like components that do work every cycle (caches, DRAM controllers) |
| Event-driven | modeling.EventDrivenComponent[S, T, R] |
Components that react to messages/events and may be idle for long periods |
Both paradigms use the same port and message infrastructure for communication.