simgo

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2021 License: MIT Imports: 4 Imported by: 2

README

SimGo

SimGo is a discrete event simulation framework for Go. It is similar to SimPy and aims to be easy to set up and use.

Processes are defined as simple functions receiving simgo.Process as their first argument. Each process is executed in a separate goroutine, but it is guarantueed that only one process is executed at a time. For examples, look into the examples folder. A short example simulating two clocks ticking in different time intervals looks like this:

package main

import (
    "fmt"

    "github.com/fschuetz04/simgo"
)

func clock(proc simgo.Process, name string, delay float64) {
    for {
        fmt.Println(name, proc.Now())
        proc.Wait(proc.Timeout(delay))
    }
}

func main() {
    sim := simgo.Simulation{}

    sim.ProcessReflect(clock, "slow", 2)
    sim.ProcessReflect(clock, "fast", 1)

    sim.RunUntil(5)
}

When run, the following output is generated:

slow 0
fast 0
fast 1
slow 2
fast 2
fast 3
slow 4
fast 4

You can find more examples in the examples directory.

Copyright © 2021 Felix Schütz.

Licensed under the MIT License. See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Awaitable added in v0.4.3

type Awaitable interface {
	// Processed must return true when the event is processed.
	Processed() bool

	// Aborted must return true when the event is aborted.
	Aborted() bool

	// AddHandler must add the given normal handler. When the event is
	// processed, the normal handler must be called.
	AddHandler(handler Handler)

	// AddAbortHandler must add the given abort handler. When the event is
	// aborted, the abort handler must be called.
	AddAbortHandler(handler Handler)
}

Awaitable represents any awaitable thing like an event.

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event is an event in a discrete-event simulation. The event does not contain information about whether it is scheduled to be processed.

To create a new event, use (*Simulation).Timeout, (*Simulation).Event, (*Simulation).AnyOf, or (*Simulation).AllOf:

ev1 := sim.Event()
ev2 := sim.Timeout(5)
ev3 := sim.AnyOf(ev1, ev2)
ev4 := sim.AllOf(ev1, ev2)

func (*Event) Abort added in v0.4.0

func (ev *Event) Abort() bool

Abort aborts the event and calls all abort handlers of the event.

If the event is not pending, it will not be aborted.

Returns true if the event has been aborted or false otherwise.

TODO(fschuetz04): Abort immediately calls it handlers, which leads to a growing call stack. Instead, the processing could be scheduled similar to that of (*Event).Trigger.

func (*Event) Aborted added in v0.4.0

func (ev *Event) Aborted() bool

Aborted returns whether the event has been aborted. All abort handlers of an] aborted event are currently being called or have been called.

func (*Event) AddAbortHandler added in v0.4.1

func (ev *Event) AddAbortHandler(handler Handler)

AddAbortHandler adds the given handler as an abort handler to the event. The handler will be called when the event is aborted.

If the event is already processed or aborted, the handler is not stored, since it will never be called.

func (*Event) AddHandler added in v0.4.1

func (ev *Event) AddHandler(handler Handler)

AddHandler adds the given handler as a normal handler to the event. The handler will be called when the event is processed.

If the event is already processed or aborted, the handler is not stored, since it will never be called.

func (*Event) Pending added in v0.4.0

func (ev *Event) Pending() bool

Pending returns whether the event is pending. A pending event has not yet been triggered or processed. This is the initial state of a new event.

func (*Event) Processed added in v0.4.0

func (ev *Event) Processed() bool

Pending returns whether the event has been processed. All normal handlers of a processed event are currently being called or have been called.

func (*Event) Trigger

func (ev *Event) Trigger() bool

Trigger schedules the event to be processed immediately. This will call all normal handlers of the event.

If the event is not pending, it will not be scheduled.

func (*Event) TriggerDelayed

func (ev *Event) TriggerDelayed(delay float64) bool

Trigger schedules the event to be processed after the given delay. This will call all normal handlers of the event.

If the event is not pending, it will not be scheduled.

Returns true if the event has been scheduled or false otherwise. Panics if the given delay is negative.

Note that an event can be triggered delayed multiple times, or triggered immediately after it is already triggered delayed. The event will be processed once at the earliest scheduled time.

func (*Event) Triggered added in v0.4.0

func (ev *Event) Triggered() bool

Pending returns whether the event has been triggered. A triggered event will be processed at the current simulation time if it has not been processed already.

type Handler added in v0.4.1

type Handler func(ev *Event)

Handler is either a normal handler or an abort handler, which is called when an event is processed / aborted. The handler gets a pointer to the relevant pointer, so one function can be used to handle multiple events and distinguish between them.

type Process

type Process struct {
	// Simulation is used to generate timeouts and other events, and start new
	// processes.
	*Simulation
	// contains filtered or unexported fields
}

Process is a process in a discrete-event simulation.

A process can wait for events and other processes, create new events and start new processes.

To start a process, use (*Simulation).Process or (*Simulation).ProcessReflect:

func myProcess (proc simgo.Process) {
    fmt.Println("Start")
    proc.Wait(proc.Timeout(5))
    fmt.Println("End")
}
sim.Process(myProcess)

Process encapsulates *Simulation, so all its methods can be used.

func (Process) Aborted added in v0.4.0

func (proc Process) Aborted() bool

Pending returns whether the underlying event is aborted.

func (Process) AddAbortHandler added in v0.4.1

func (proc Process) AddAbortHandler(handler Handler)

AddAbortHandler adds the given abort handler to the underlying event.

func (Process) AddHandler added in v0.4.1

func (proc Process) AddHandler(handler Handler)

AddHandler adds the given handler to the underlying event.

func (Process) Pending added in v0.4.0

func (proc Process) Pending() bool

Pending returns whether the underlying event is pending.

func (Process) Processed added in v0.4.0

func (proc Process) Processed() bool

Pending returns whether the underlying event is processed.

func (Process) Triggered added in v0.4.0

func (proc Process) Triggered() bool

Triggered retrusn whether the underlying event is triggered.

func (Process) Wait

func (proc Process) Wait(ev Awaitable)

Wait yields from the process to the simulation and waits until the given awaitable is processed.

If the awaitable is already processed, the process is not paused. If the awaitable is aborted, the process is aborted too.

type Simulation

type Simulation struct {
	// contains filtered or unexported fields
}

Simulation runs a discrete-event simulation.

To create a new simulation, use the default struct:

sim := simgo.Simulation{}
sim.Process(myProcess)
sim.Run()

func (*Simulation) AllOf added in v0.2.2

func (sim *Simulation) AllOf(evs ...Awaitable) *Event

AllOf creates and returns a pending event which is triggered when all of the given events are processed.

func (*Simulation) AnyOf added in v0.2.2

func (sim *Simulation) AnyOf(evs ...Awaitable) *Event

AnyOf creates and returns a pending event which is triggered when any of the given events is processed.

func (*Simulation) Event

func (sim *Simulation) Event() *Event

Event creates and returns a pending event.

func (*Simulation) Now

func (sim *Simulation) Now() float64

Now returns the current simulation time.

func (*Simulation) Process added in v0.4.0

func (sim *Simulation) Process(runner func(proc Process)) Process

Process starts a new process with the given runner.

Creates and triggers an event. As soon as this event is processed, the runner is executed. Whenever the runner waits for a pending event, it is paused until the event is processed.

It is ensured that only one process is executed at the same time.

Returns the process. This can be used to wait for the process to finish. As soon as the process finishes, the underlying event is triggered.

func (*Simulation) ProcessReflect added in v0.4.0

func (sim *Simulation) ProcessReflect(runner interface{}, args ...interface{}) Process

ProcessReflect starts a new process with the given runner and the given additional argument. This uses reflection.

See (*Simulation).Process for further documentation.

func (*Simulation) Run

func (sim *Simulation) Run()

Run runs the simulation until the event queue is empty.

func (*Simulation) RunUntil

func (sim *Simulation) RunUntil(target float64)

RunUntil runs the simulation until the event queue is empty or the next event in the event queue is scheduled at or after the given target time. Sets the current simulation time to the target time at the end.

Panics if the given target time is smaller than the current simulation time.

func (*Simulation) Step

func (sim *Simulation) Step() bool

Step sets the current simulation time to the scheduled time of the next event in the event queue and processes the next event. Returns false if the event queue was empty and no event was processed, true otherwise.

func (*Simulation) Timeout

func (sim *Simulation) Timeout(delay float64) *Event

Timeout creates and returns a pending event which is processed after the given delay.

Panics if the given delay is negative.

Directories

Path Synopsis
_examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL