Skip to content

Commit d9fb051

Browse files
committed
Add Docs, triggered is processed now
1 parent 675bcb6 commit d9fb051

File tree

11 files changed

+74
-14
lines changed

11 files changed

+74
-14
lines changed

docs/src/guides/basics.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The environment stores these events in its event list and keeps track of the cur
1414

1515
If a process function yields an event, SimJulia adds the process to the event’s callbacks and suspends the process until the event is triggered and processed. When a process waiting for an event is resumed, it will also receive the event’s value.
1616

17-
Here is a very simple example that illustrates all this; the code is more verbose than it needs to be to make things extra clear. You find a compact version of it at the end of this section:
17+
Here is a very simple example that illustrates all this:
1818

1919
```jldoctest
2020
using ResumableFunctions
@@ -45,5 +45,5 @@ If all required process functions are defined, you can instantiate all objects f
4545

4646
Starting a process function involves two things:
4747

48-
- You have to call the macro `@process` with as argument a function call to the process function. (This will not execute any code of that function yet.) This will schedule an initialisation event at the current simulation time which starts the execution of the process function. The process instance is also an event that is triggered when the process function returns.
48+
- You have to call the macro `@process` with as argument a call to the process function. (This will not execute any code of that function yet.) This will schedule an initialisation event at the current simulation time which starts the execution of the process function. The process instance is also an event that is triggered when the process function returns.
4949
- Finally, you can start SimJulia’s event loop. By default, it will run as long as there are events in the event list, but you can also let it stop earlier by providing an until argument.

docs/src/guides/events.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,61 @@
11
# Events
2+
3+
SimJulia includes an extensive set of event types for various purposes. All of them are descendants of `AbstractEvent`. Here the following events are discussed:
4+
5+
- `Event`
6+
- `Timeout`
7+
- `Operator`
8+
9+
The guide to resources describes the various resource events.
10+
11+
## Event basics
12+
13+
SimJulia events are very similar – if not identical — to deferreds, futures or promises. Instances of the type AbstractEvent are used to describe any kind of events. Events can be in one of the following states. An event:
14+
15+
- might happen (idle),
16+
- is going to happen (scheduled) or
17+
- has happened (processed).
18+
19+
They traverse these states exactly once in that order. Events are also tightly bound to time and time causes events to advance their state.
20+
21+
Initially, events are idle and the function `state` returns `SimJulia.idle`.
22+
23+
If an event gets scheduled at a given time, it is inserted into SimJulia’s event queue. The function `state` returns `SimJulia.scheduled`.
24+
25+
As long as the event is not processed, you can add callbacks to an event. Callbacks are function having an `AbstractEvent` as first parameter.
26+
27+
An event becomes processed when SimJulia pops it from the event queue and calls all of its callbacks. It is now no longer possible to add callbacks. The function `state` returns `SimJulia.processed`.
28+
29+
Events also have a value. The value can be set before or when the event is scheduled and can be retrieved via the function `value` or, within a process, by yielding the event (`value = @yield event`).
30+
31+
## Adding callbacks to an event
32+
33+
“What? Callbacks? I’ve never seen no callbacks!”, you might think if you have worked your way through the tutorial.
34+
35+
That’s on purpose. The most common way to add a callback to an event is yielding it from your process function (`@yield event`). This will add the process’ `resume` function as a callback. That’s how your process gets resumed when it yielded an event.
36+
37+
However, you can add any function to the list of callbacks as long as it accepts `AbstractEvent` or a descendant as first parameter:
38+
39+
```jldoctest
40+
julia> using SimJulia
41+
42+
julia> function my_callback(ev::AbstractEvent)
43+
println("Called back from ", ev)
44+
end
45+
my_callback (generic function with 1 method)
46+
47+
julia> sim = Simulation()
48+
SimJulia.Simulation time: 0.0 active_process: nothing
49+
50+
julia> ev = Event(sim)
51+
SimJulia.Event 1
52+
53+
julia> @callback my_callback(ev)
54+
(::#3) (generic function with 1 method)
55+
56+
julia> succeed(ev)
57+
SimJulia.Event 1
58+
59+
julia> run(sim)
60+
Called back from SimJulia.Event 1
61+
```

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
SimJulia is a discrete-event process-oriented simulation framework written in [Julia](http://julialang.org/) inspired by the Python library [SimPy](https://simpy.readthedocs.io/). Its process dispatcher is based on semi-coroutines scheduling as implemented in [ResumableFunctions](https://github.com/BenLauwens/ResumableFunctions.jl.git). A `Process` in SimJulia is defined by a `@resumable function` yielding `Events`. SimJulia provides three types of shared resources to model limited capacity congestion points: `Resources`, `Containers` and `Stores`. The API is modeled after the SimPy API but some specific Julia semantics are used.
44

5-
The documentation contains a tutorial, topical guides explaining key concepts, a number of examples and the API reference. The tutorial, the topical guides and some examples are borrowed from the SimPy to allow a direct comparison and an easy migration path for users. The differences between SimJulia and SimPy are clearly documented.
5+
The documentation contains a tutorial, topical guides explaining key concepts, a number of examples and the API reference. The tutorial, the topical guides and some examples are borrowed from SimPy to allow a direct comparison and an easy migration path for users. The differences between SimJulia and SimPy are clearly documented.
66

77
## Example
88

src/base.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
abstract type AbstractEvent end
22
abstract type Environment end
33

4-
@enum EVENT_STATE idle=0 scheduled=1 triggered=2
4+
@enum EVENT_STATE idle=0 scheduled=1 processed=2
55

6-
struct EventTriggered <: Exception
6+
struct EventProcessed <: Exception
77
ev :: AbstractEvent
88
end
99

@@ -44,7 +44,7 @@ function state(ev::AbstractEvent) :: EVENT_STATE
4444
end
4545

4646
function append_callback(func::Function, ev::AbstractEvent, args::Any...) :: Function
47-
ev.bev.state == triggered && throw(EventTriggered(ev))
47+
ev.bev.state == processed && throw(EventProcessed(ev))
4848
cb = ()->func(ev, args...)
4949
push!(ev.bev.callbacks, cb)
5050
cb

src/events.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ end
77

88
function succeed(ev::Event; priority::Int8=zero(Int8), value::Any=nothing) :: Event
99
sta = state(ev)
10-
(sta == scheduled || sta == triggered) && throw(EventNotIdle(ev))
10+
(sta == scheduled || sta == processed) && throw(EventNotIdle(ev))
1111
schedule(ev; priority=priority, value=value)
1212
ev
1313
end

src/old/processes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ end
3939
function yield(target::AbstractEvent)
4040
env = environment(target)
4141
proc = active_process(env)
42-
proc.target = state(target) == triggered ? Timeout(env; value=value(target)) : target
42+
proc.target = state(target) == processed ? Timeout(env; value=value(target)) : target
4343
proc.resume = @callback execute(proc.target, proc)
4444
ret = SimJulia.produce(nothing)
4545
isa(ret, Exception) && throw(ret)

src/operators.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ function check(ev::AbstractEvent, op::Operator, event_state_values::Dict{Abstrac
4040
end
4141

4242
function eval_and(state_values::Vector{StateValue})
43-
all(map((sv)->sv.state == triggered, state_values))
43+
all(map((sv)->sv.state == processed, state_values))
4444
end
4545

4646
function eval_or(state_values::Vector{StateValue})
47-
any(map((sv)->sv.state == triggered, state_values))
47+
any(map((sv)->sv.state == processed, state_values))
4848
end
4949

5050
function (&)(ev1::AbstractEvent, ev2::AbstractEvent)

src/processes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function execute(ev::AbstractEvent, proc::Process)
2929
if done(proc.fsm)
3030
schedule(proc; value=target)
3131
else
32-
proc.target = state(target) == triggered ? Timeout(env; value=value(target)) : target
32+
proc.target = state(target) == processed ? Timeout(env; value=value(target)) : target
3333
proc.resume = @callback execute(proc.target, proc)
3434
end
3535
catch exc

src/resources/containers.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function request(func::Function, res::Resource; priority::Int=0)
3939
try
4040
func(req)
4141
finally
42-
if state(req) == triggered
42+
if state(req) == processed
4343
yield(Release(res; priority=priority))
4444
else
4545
cancel(res, req)

src/simulations.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function step(sim::Simulation)
3434
(bev, key) = DataStructures.peek(sim.heap)
3535
DataStructures.dequeue!(sim.heap)
3636
sim.time = key.time
37-
bev.state = triggered
37+
bev.state = processed
3838
for callback in bev.callbacks
3939
callback()
4040
end

0 commit comments

Comments
 (0)