You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,8 @@
2
2
3
3
## v1.0.1 - dev
4
4
5
-
- Start using `Base`'s API: `lock`, `trylock`, `unlock`, `islocked`, `isready`, `get!` and deprecate `get`, `request`, `release`.
5
+
- Start using `Base`'s API: `lock`, `trylock`, `unlock`, `islocked`, `isready`, `put!`, `take!`. Deprecate `put`, `request`, `release`. Moreover, consider using `take!` instead of `get` (which was not deprecated as it has numerous internal uses).
Copy file name to clipboardExpand all lines: docs/src/examples/Latency.md
+55-33Lines changed: 55 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,27 +7,32 @@ In this example we show how to separate the time delay between processes from th
7
7
### Load Packages
8
8
9
9
10
-
```julia
10
+
```jldoctest 1; output = false
11
11
using ConcurrentSim
12
12
using ResumableFunctions
13
-
import Base: put!, get
13
+
import Base: put!, take!
14
+
15
+
# output
14
16
```
15
17
16
18
### Define Constants
17
19
18
20
19
-
```julia
20
-
srand(8710) # set random number seed for reproducibility
21
+
```jldoctest 1; output = false
21
22
const SIM_DURATION = 100.
22
23
const SEND_PERIOD = 5.0
23
24
const RECEIVE_PERIOD = 3.0;
25
+
26
+
nothing # hide
27
+
28
+
# output
24
29
```
25
30
26
31
### Define Cable model
27
32
The `Cable` contains reference to the simulation it is part of, the delay that messages experience, and a store that contains the sent messages
28
33
29
34
30
-
```julia
35
+
```jldoctest 1; output = false
31
36
mutable struct Cable
32
37
env::Simulation
33
38
delay::Float64
@@ -37,35 +42,47 @@ mutable struct Cable
37
42
return new(env, delay, Store{String}(env))
38
43
end
39
44
end;
45
+
46
+
nothing # hide
47
+
48
+
# output
40
49
```
41
50
42
51
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.
43
52
44
53
45
-
```julia
54
+
```jldoctest 1; output = false
46
55
@resumable function latency(env::Simulation, cable::Cable, value::String)
47
56
@yield timeout(cable.env, cable.delay)
48
57
@yield put!(cable.store, value)
49
-
end;
58
+
end;
59
+
60
+
nothing # hide
61
+
62
+
# output
50
63
```
51
64
52
-
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).
65
+
The `put!` and `take!` 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).
53
66
54
67
55
-
```julia
68
+
```jldoctest 1; output = false
56
69
function put!(cable::Cable, value::String)
57
70
@process latency(cable.env, cable, value) # results in the scheduling of all events generated by latency
58
71
end
59
72
60
-
functionget(cable::Cable)
61
-
get(cable.store) # returns an element stored in the cable store
73
+
function take!(cable::Cable); output = false
74
+
take!(cable.store) # returns an element stored in the cable store
62
75
end;
76
+
77
+
nothing # hide
78
+
79
+
# output
63
80
```
64
81
65
82
The `sender` and `receiver` generators yield events to the simulator.
66
83
67
84
68
-
```julia
85
+
```jldoctest 1; output = false
69
86
@resumable function sender(env::Simulation, cable::Cable)
70
87
while true
71
88
@yield timeout(env, SEND_PERIOD)
@@ -77,39 +94,44 @@ end
77
94
@resumable function receiver(env::Simulation, cable::Cable)
78
95
while true
79
96
@yield timeout(env, RECEIVE_PERIOD)
80
-
msg =@yieldget(cable)
97
+
msg = @yield take!(cable)
81
98
println("Received this at $(now(env)) while $msg")
82
99
end
83
100
end;
101
+
102
+
nothing # hide
103
+
104
+
# output
84
105
```
85
106
86
107
Create simulation, register events, and run!
87
108
88
109
89
-
```julia
110
+
```jldoctest 1
90
111
env = Simulation()
91
112
cable = Cable(env, 10.)
92
113
@process sender(env, cable)
93
114
@process receiver(env, cable)
94
115
95
116
run(env, SIM_DURATION)
96
-
```
97
-
98
-
Received this at 15.0 while sender sent this at 5.0
99
-
Received this at 20.0 while sender sent this at 10.0
100
-
Received this at 25.0 while sender sent this at 15.0
101
-
Received this at 30.0 while sender sent this at 20.0
102
-
Received this at 35.0 while sender sent this at 25.0
103
-
Received this at 40.0 while sender sent this at 30.0
104
-
Received this at 45.0 while sender sent this at 35.0
105
-
Received this at 50.0 while sender sent this at 40.0
106
-
Received this at 55.0 while sender sent this at 45.0
107
-
Received this at 60.0 while sender sent this at 50.0
108
-
Received this at 65.0 while sender sent this at 55.0
109
-
Received this at 70.0 while sender sent this at 60.0
110
-
Received this at 75.0 while sender sent this at 65.0
111
-
Received this at 80.0 while sender sent this at 70.0
112
-
Received this at 85.0 while sender sent this at 75.0
113
-
Received this at 90.0 while sender sent this at 80.0
114
-
Received this at 95.0 while sender sent this at 85.0
115
117
118
+
# output
119
+
120
+
Received this at 15.0 while sender sent this at 5.0
121
+
Received this at 20.0 while sender sent this at 10.0
122
+
Received this at 25.0 while sender sent this at 15.0
123
+
Received this at 30.0 while sender sent this at 20.0
124
+
Received this at 35.0 while sender sent this at 25.0
125
+
Received this at 40.0 while sender sent this at 30.0
126
+
Received this at 45.0 while sender sent this at 35.0
127
+
Received this at 50.0 while sender sent this at 40.0
128
+
Received this at 55.0 while sender sent this at 45.0
129
+
Received this at 60.0 while sender sent this at 50.0
130
+
Received this at 65.0 while sender sent this at 55.0
131
+
Received this at 70.0 while sender sent this at 60.0
132
+
Received this at 75.0 while sender sent this at 65.0
133
+
Received this at 80.0 while sender sent this at 70.0
134
+
Received this at 85.0 while sender sent this at 75.0
135
+
Received this at 90.0 while sender sent this at 80.0
136
+
Received this at 95.0 while sender sent this at 85.0
A store is a resource that can hold a number of items of type `T`. It is similar to a `Base.Channel` with a finite capacity ([`put!`](@ref) blocks after reaching capacity).
18
+
The [`put!`](@ref) and [`take!`](@ref) functions are a convenient way to interact with such a "channel" in a way mostly compatible with other discrete event and concurrency frameworks.
19
+
20
+
See [`Container`](@ref) for a more lock-like resource.
21
+
22
+
Think of `Resource` and `Container` as locks and of `Store` as channels. They block only if empty (on taking) or full (on storing).
unlock(::Store) =error("There is no well defined way to \"unlock\" a store. Instead of attempting `unlock` consider using `pop!(::Store)` or use a `Resource` instead of a `Store`.")
104
-
lock(::Store) =error("There is no well defined way to \"lock\" a store. Instead of attempting `lock` consider using `put!(::Store, ...)` or use a `Resource` instead of a `Store`.")
105
-
trylock(::Store) =error("There is no well defined way to \"lock\" a store. Instead of attempting `lock` consider using `put!(::Store, ...)` or use a `Resource` instead of a `Store`.")
118
+
unlock(::Store) =error("There is no well defined way to \"unlock\" a Store without taking an element out of it. Instead of attempting `unlock` consider using `take!(::Store)` or use a `Resource` instead of a `Store`. Think of `Resource` and `Container` as locks and of `Store` as channels. They block only if empty (on taking) or full (on storing).")
119
+
lock(::Store) =error("There is no well defined way to \"lock\" a Store without storing an element in it. Instead of attempting `lock` consider using `put!(::Store, ...)` or use a `Resource` instead of a `Store`. Think of `Resource` and `Container` as locks and of `Store` as channels. They block only if empty (on taking) or full (on storing).")
120
+
trylock(::Store) =error("There is no well defined way to \"lock\" a Store without storing an element in it. Instead of attempting `lock` consider using `put!(::Store, ...)` or use a `Resource` instead of a `Store`. Think of `Resource` and `Container` as locks and of `Store` as channels. They block only if empty (on taking) or full (on storing).")
106
121
107
122
"""
108
123
take!(::Store)
109
124
110
125
An alias for `get(::Store)` for easier interoperability with the `Base.Channel` interface. Blocks if the store is empty.
0 commit comments