Skip to content

Commit 8682762

Browse files
committed
implement take!
1 parent bc80081 commit 8682762

File tree

6 files changed

+43
-2
lines changed

6 files changed

+43
-2
lines changed

src/ConcurrentSim.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module ConcurrentSim
77
using Dates
88
using ResumableFunctions
99

10-
import Base: run, isless, show, yield, get, put!, isready, islocked, unlock, lock, trylock, &, |
10+
import Base: run, isless, show, yield, get, put!, take!, isready, islocked, unlock, lock, trylock, &, |
1111
import Dates: now
1212

1313
export AbstractEvent, Environment, value, state, environment

src/resources/containers.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,5 @@ true
112112
```
113113
"""
114114
islocked(c::Container) = c.level==c.capacity
115+
116+
take!(::Container, args...) = error("There is no well defined `take!` for `Container`. Instead of attempting `take!` consider using `unlock(::Container)` or use a `Store` instead of a `Resource` or `Container`. Think of `Resource` and `Container` as locks and of `Store` as channels. They block only if empty (on taking) or full (on storing).")

src/resources/stores.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,10 @@ islocked(sto::Store) = sto.load==sto.capacity
103103
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`.")
104104
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`.")
105105
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`.")
106+
107+
"""
108+
take!(::Store)
109+
110+
An alias for `get(::Store)` for easier interoperability with the `Base.Channel` interface. Blocks if the store is empty.
111+
"""
112+
take!(sto::Store{T}, filter::Function=get_any_item; priority::Int=0) where {T} = get(sto, filter; priority)

test/test_resources_containers.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,5 @@ con = Container(sim, 10.0; level=5.0)
5959
@process my_consumer(sim, con)
6060
@process my_producer(sim, con)
6161
run(sim)
62+
63+
@test_throws ErrorException take!(con)

test/test_resources_stores.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ end
99
for j in 1:10
1010
@yield timeout(sim, rand())
1111
println("$(now(sim)), consumer is demanding object")
12-
obj = @yield get(sto)
12+
obj = @yield take!(sto)
1313
println("$(now(sim)), consumer is being served with object ", obj.i)
1414
end
1515
end
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using ConcurrentSim
2+
using ResumableFunctions
3+
4+
struct StoreObject
5+
i :: Int
6+
end
7+
8+
@resumable function my_consumer(sim::Simulation, sto::Store)
9+
for j in 1:10
10+
@yield timeout(sim, rand())
11+
println("$(now(sim)), consumer is demanding object")
12+
obj = @yield get(sto) # "unofficially" deprecated
13+
println("$(now(sim)), consumer is being served with object ", obj.i)
14+
end
15+
end
16+
17+
@resumable function my_producer(sim::Simulation, sto::Store)
18+
for j in 1:10
19+
println("$(now(sim)), producer is offering object $j")
20+
@yield put!(sto, StoreObject(j))
21+
println("$(now(sim)), producer is being served")
22+
@yield timeout(sim, 2*rand())
23+
end
24+
end
25+
26+
sim = Simulation()
27+
sto = Store{StoreObject}(sim)
28+
@process my_consumer(sim, sto)
29+
@process my_producer(sim, sto)
30+
run(sim)

0 commit comments

Comments
 (0)