-
I am trying to write a simple program to simulate a series of 2 queuing servers, but I believe I'm misunderstanding the My intention was to simulate this type of system: (Client arrivals) -> [Queue A] -> {Server A} -> [Queue B] -> {Server B} -> (Departures) I based it off of the call center example, but instead of using processes for the servers, I've instead used events based on conditions of the 2 servers, where the serve event for server A fills the input queue for server B. Would it not be recommended to do this? Any advice would be appreciated! Edit: Forgot to mention I'm using Julia 1.8.5 and the latest release of DiscreteEvents. # Tandem Queue infinite buffer size
using DiscreteEvents, Distributions, Random, Printf
mutable struct Client
id::Int
arrivalA::Float64 # arrival time at Server A
arrivalB::Float64 # arrival time at Server B
serviceA::Float64 # beginning of service time at Server A
serviceB::Float64 # beginning of service time at Server B
departure::Float64 # end of service time
end
mutable struct Server
id::Int
svcdist::Distribution
isbusy::Bool
tbusy::Float64
end
function serve(clk, srvr, input, output, limit)
srvr.isbusy = true
client = take!(input)
st = clk.time
if srvr.id == 1
client.serviceA = clk.time
else
client.serviceB = clk.time
end
@delay clk rand(srvr.svcdist)
if srvr.id == 1
client.departureA = clk.time
else
client.departureB = clk.time
end
srvr.tbusy += client.departure - st
push!(output, client)
client.id >= limit && stop!(clk)
srvr.isbusy = false
end
function arrive(clk, input, count)
count[1] += 1
put!(input, Client(count[1], clk.time, 0.0, 0.0, 0.0, 0.0))
end
Random.seed!(42)
const N = 1000
const M_serve = Exponential(1.0)
const M_arr = Exponential(1.0/0.3)
count = [0]
clock = Clock()
input_a = Channel{Client}(Inf)
input_b = Channel{Client}(Inf)
output = Client[]
srvr_a = Server(1, M_serve, false, 0.0)
srvr_b = Server(2, M_serve, false, 0.0)
@event serve(clock, srvr_a, input_a, input_b, N) ()->!isempty(input_a) && !srvr_a.isbusy
@event serve(clock, srvr_b, input_b, output, N) ()->!isempty(input_b) && !srvr_b.isbusy
@event arrive(clock, input_a, count) every M_arr
@run! clock 5000 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @tv-deusen, Thanks for reaching out. I made some changes to your code and got it to work. The main changes were:
Note: With these changes, the # Tandem Queue infinite buffer size
using DiscreteEvents, Distributions, Random, Printf
mutable struct Client
id::Int
arrivalA::Float64 # arrival time at Server A
arrivalB::Float64 # arrival time at Server B
serviceA::Float64 # beginning of service time at Server A
serviceB::Float64 # beginning of service time at Server B
departureA::Float64 # end of service time
departureB::Float64 # end of service time
end
mutable struct Server
id::Int
svcdist::Distribution
isbusy::Bool
tbusy::Float64
end
function serve(clk, srvr, input, output, limit)
srvr.isbusy = true
client = take!(input)
st = clk.time
if srvr.id == 1
client.serviceA = clk.time
else
client.arrivalB = client.departureA
client.serviceB = clk.time
end
@delay clk rand(srvr.svcdist)
if srvr.id == 1
client.departureA = clk.time
else
client.departureB = clk.time
end
srvr.tbusy += clk.time - st
push!(output, client)
srvr.id == 2 && client.id >= limit && stop!(clk)
srvr.isbusy = false
end
function arrive(clk, input, count)
count[1] += 1
put!(input, Client(count[1], clk.time, 0.0, 0.0, 0.0, 0.0, 0.0))
end
Random.seed!(42)
const N = 1000
const M_serve = Exponential(1.0)
const M_arr = Exponential(1.0/0.3)
count = [0]
clock = Clock()
input_a = Channel{Client}(Inf)
input_b = Channel{Client}(Inf)
output = Client[]
srvr_a = Server(1, M_serve, false, 0.0)
srvr_b = Server(2, M_serve, false, 0.0)
@process serve(clock, srvr_a, input_a, input_b, N)
@process serve(clock, srvr_b, input_b, output, N)
# @event serve(clock, srvr_a, input_a, input_b, N) ()->!isempty(input_a) && !srvr_a.isbusy
# @event serve(clock, srvr_b, input_b, output, N) ()->!isempty(input_b) && !srvr_b.isbusy
@event arrive(clock, input_a, count) every M_arr
@run! clock 5000 |
Beta Was this translation helpful? Give feedback.
Hi @tv-deusen,
Thanks for reaching out. I made some changes to your code and got it to work. The main changes were:
departA
anddepartB
fields on the client, which do not exist in the struct. This points to an another issue where the error is not being thrown. I added these fields so that they can be updated properly.@event
macros with@process
macros forserve
as is done in the call center exampleNote: With these changes, the
isbusy
field for the server is no longer relevant.