Skip to content

Commit ef44860

Browse files
authored
Merge pull request #55 from riccardosven/master
Added Latency example
2 parents 3ddd396 + 2d643fd commit ef44860

File tree

3 files changed

+333
-1
lines changed

3 files changed

+333
-1
lines changed

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ makedocs(
1111
"Topical Guides" => ["Basics" => "guides/basics.md",
1212
"Environments" => "guides/environments.md",
1313
"Events" => "guides/events.md",],
14-
"Examples" => ["Ross" => "examples/ross.md",],
14+
"Examples" => ["Ross" => "examples/ross.md", "Latency" =>
15+
"examples/Latency.md"],
1516
"API" => "api.md"
1617
]
1718
)

docs/src/examples/Latency.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
2+
# Event Latency
3+
4+
## Description
5+
In this example we show how to separate the time delay between processes from the processes themselves. We model a communications channel, called a `Cable`, where a sender sends messages regularly each `SEND_PERIOD` time units and a receiver listens each `RECEIVE_PERIOD`. The messages in the cable have a delay fo `DELAY_DURATION` until they reach the recevier.
6+
7+
### Load Packages
8+
9+
10+
```julia
11+
using SimJulia
12+
using ResumableFunctions
13+
import SimJulia.put
14+
import Base.get
15+
```
16+
17+
### Define Constants
18+
19+
20+
```julia
21+
srand(8710) # set random number seed for reproducibility
22+
const SIM_DURATION = 100.
23+
const SEND_PERIOD = 5.0
24+
const RECEIVE_PERIOD = 3.0;
25+
```
26+
27+
### Define Cable model
28+
The `Cable` contains reference to the simulation it is part of, the delay that messages experience, and a store that contains the sent messages
29+
30+
31+
```julia
32+
mutable struct Cable
33+
env::Simulation
34+
delay::Float64
35+
store::Store{String}
36+
37+
function Cable(env::Simulation, delay::Float64)
38+
return new(env, delay, Store{String}(env))
39+
end
40+
end;
41+
```
42+
43+
The latency function is a generator which yields two events: first a `timeout` that represents the transmission delay, then a put event when the message gets stored in the store.
44+
45+
46+
```julia
47+
@resumable function latency(env::Simulation, cable::Cable, value::String)
48+
@yield timeout(cable.env, cable.delay)
49+
@yield put(cable.store, value)
50+
end;
51+
```
52+
53+
The `put` and `get` functions allow interaction with the cable (note that these are not `@resumable` because they need to return the result of the operation and not the operation itself).
54+
55+
56+
```julia
57+
function put(cable::Cable, value::String)
58+
@process latency(cable.env, cable, value) # results in the scheduling of all events generated by latency
59+
end
60+
61+
function get(cable::Cable)
62+
get(cable.store) # returns an element stored in the cable store
63+
end;
64+
```
65+
66+
The `sender` and `receiver` generators yield events to the simulator.
67+
68+
69+
```julia
70+
@resumable function sender(env::Simulation, cable::Cable)
71+
while true
72+
@yield timeout(env, SEND_PERIOD)
73+
value = "sender sent this at $(now(env))"
74+
put(cable, value)
75+
end
76+
end
77+
78+
@resumable function receiver(env::Simulation, cable::Cable)
79+
while true
80+
@yield timeout(env, RECEIVE_PERIOD)
81+
msg = @yield get(cable)
82+
println("Received this at $(now(env)) while $msg")
83+
end
84+
end;
85+
```
86+
87+
Create simulation, register events, and run!
88+
89+
90+
```julia
91+
env = Simulation()
92+
cable = Cable(env, 10.)
93+
@process sender(env, cable)
94+
@process receiver(env, cable)
95+
96+
run(env, SIM_DURATION)
97+
```
98+
99+
Received this at 15.0 while sender sent this at 5.0
100+
Received this at 20.0 while sender sent this at 10.0
101+
Received this at 25.0 while sender sent this at 15.0
102+
Received this at 30.0 while sender sent this at 20.0
103+
Received this at 35.0 while sender sent this at 25.0
104+
Received this at 40.0 while sender sent this at 30.0
105+
Received this at 45.0 while sender sent this at 35.0
106+
Received this at 50.0 while sender sent this at 40.0
107+
Received this at 55.0 while sender sent this at 45.0
108+
Received this at 60.0 while sender sent this at 50.0
109+
Received this at 65.0 while sender sent this at 55.0
110+
Received this at 70.0 while sender sent this at 60.0
111+
Received this at 75.0 while sender sent this at 65.0
112+
Received this at 80.0 while sender sent this at 70.0
113+
Received this at 85.0 while sender sent this at 75.0
114+
Received this at 90.0 while sender sent this at 80.0
115+
Received this at 95.0 while sender sent this at 85.0
116+

examples/Latency.ipynb

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Event Latency\n",
8+
"\n",
9+
"## Description \n",
10+
"In this example we show how to separate the time delay between processes from the processes themselves. We model a communications channel, called a `Cable`, where a sender sends messages regularly each `SEND_PERIOD` time units and a receiver listens each `RECEIVE_PERIOD`. The messages in the cable have a delay fo `DELAY_DURATION` until they reach the recevier."
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"### Load Packages"
18+
]
19+
},
20+
{
21+
"cell_type": "code",
22+
"execution_count": 19,
23+
"metadata": {},
24+
"outputs": [],
25+
"source": [
26+
"using SimJulia\n",
27+
"using ResumableFunctions\n",
28+
"import SimJulia.put\n",
29+
"import Base.get"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"metadata": {},
35+
"source": [
36+
"### Define Constants"
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": 23,
42+
"metadata": {},
43+
"outputs": [],
44+
"source": [
45+
"srand(8710) # set random number seed for reproducibility\n",
46+
"const SIM_DURATION = 100.\n",
47+
"const SEND_PERIOD = 5.0\n",
48+
"const RECEIVE_PERIOD = 3.0;"
49+
]
50+
},
51+
{
52+
"cell_type": "markdown",
53+
"metadata": {},
54+
"source": [
55+
"### Define Cable model\n",
56+
"The `Cable` contains reference to the simulation it is part of, the delay that messages experience, and a store that contains the sent messages"
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": 24,
62+
"metadata": {},
63+
"outputs": [],
64+
"source": [
65+
"mutable struct Cable\n",
66+
" env::Simulation\n",
67+
" delay::Float64\n",
68+
" store::Store{String}\n",
69+
" \n",
70+
" function Cable(env::Simulation, delay::Float64)\n",
71+
" return new(env, delay, Store{String}(env))\n",
72+
" end\n",
73+
"end;"
74+
]
75+
},
76+
{
77+
"cell_type": "markdown",
78+
"metadata": {},
79+
"source": [
80+
"The latency function is a generator which yields two events: first a `timeout` that represents the transmission delay, then a put event when the message gets stored in the store."
81+
]
82+
},
83+
{
84+
"cell_type": "code",
85+
"execution_count": 25,
86+
"metadata": {},
87+
"outputs": [],
88+
"source": [
89+
"@resumable function latency(env::Simulation, cable::Cable, value::String)\n",
90+
" @yield timeout(cable.env, cable.delay)\n",
91+
" @yield put(cable.store, value)\n",
92+
" end;"
93+
]
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"metadata": {},
98+
"source": [
99+
"The `put` and `get` functions allow interaction with the cable (note that these are not `@resumable` because they need to return the result of the operation and not the operation itself)."
100+
]
101+
},
102+
{
103+
"cell_type": "code",
104+
"execution_count": 26,
105+
"metadata": {},
106+
"outputs": [],
107+
"source": [
108+
"function put(cable::Cable, value::String)\n",
109+
" @process latency(cable.env, cable, value) # results in the scheduling of all events generated by latency\n",
110+
"end\n",
111+
"\n",
112+
"function get(cable::Cable)\n",
113+
" get(cable.store) # returns an element stored in the cable store\n",
114+
"end;"
115+
]
116+
},
117+
{
118+
"cell_type": "markdown",
119+
"metadata": {},
120+
"source": [
121+
"The `sender` and `receiver` generators yield events to the simulator."
122+
]
123+
},
124+
{
125+
"cell_type": "code",
126+
"execution_count": 27,
127+
"metadata": {},
128+
"outputs": [],
129+
"source": [
130+
"@resumable function sender(env::Simulation, cable::Cable)\n",
131+
" while true\n",
132+
" @yield timeout(env, SEND_PERIOD)\n",
133+
" value = \"sender sent this at $(now(env))\"\n",
134+
" put(cable, value)\n",
135+
" end\n",
136+
"end\n",
137+
"\n",
138+
"@resumable function receiver(env::Simulation, cable::Cable)\n",
139+
" while true\n",
140+
" @yield timeout(env, RECEIVE_PERIOD)\n",
141+
" msg = @yield get(cable)\n",
142+
" println(\"Received this at $(now(env)) while $msg\")\n",
143+
" end\n",
144+
"end;"
145+
]
146+
},
147+
{
148+
"cell_type": "markdown",
149+
"metadata": {},
150+
"source": [
151+
"Create simulation, register events, and run!"
152+
]
153+
},
154+
{
155+
"cell_type": "code",
156+
"execution_count": 29,
157+
"metadata": {},
158+
"outputs": [
159+
{
160+
"name": "stdout",
161+
"output_type": "stream",
162+
"text": [
163+
"Received this at 15.0 while sender sent this at 5.0\n",
164+
"Received this at 20.0 while sender sent this at 10.0\n",
165+
"Received this at 25.0 while sender sent this at 15.0\n",
166+
"Received this at 30.0 while sender sent this at 20.0\n",
167+
"Received this at 35.0 while sender sent this at 25.0\n",
168+
"Received this at 40.0 while sender sent this at 30.0\n",
169+
"Received this at 45.0 while sender sent this at 35.0\n",
170+
"Received this at 50.0 while sender sent this at 40.0\n",
171+
"Received this at 55.0 while sender sent this at 45.0\n",
172+
"Received this at 60.0 while sender sent this at 50.0\n",
173+
"Received this at 65.0 while sender sent this at 55.0\n",
174+
"Received this at 70.0 while sender sent this at 60.0\n",
175+
"Received this at 75.0 while sender sent this at 65.0\n",
176+
"Received this at 80.0 while sender sent this at 70.0\n",
177+
"Received this at 85.0 while sender sent this at 75.0\n",
178+
"Received this at 90.0 while sender sent this at 80.0\n",
179+
"Received this at 95.0 while sender sent this at 85.0\n"
180+
]
181+
}
182+
],
183+
"source": [
184+
"env = Simulation()\n",
185+
"cable = Cable(env, 10.)\n",
186+
"@process sender(env, cable)\n",
187+
"@process receiver(env, cable)\n",
188+
"\n",
189+
"run(env, SIM_DURATION)"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": null,
195+
"metadata": {},
196+
"outputs": [],
197+
"source": []
198+
}
199+
],
200+
"metadata": {
201+
"kernelspec": {
202+
"display_name": "Julia 0.6.2",
203+
"language": "julia",
204+
"name": "julia-0.6"
205+
},
206+
"language_info": {
207+
"file_extension": ".jl",
208+
"mimetype": "application/julia",
209+
"name": "julia",
210+
"version": "0.6.2"
211+
}
212+
},
213+
"nbformat": 4,
214+
"nbformat_minor": 2
215+
}

0 commit comments

Comments
 (0)