Ok. So I have this code in Julia:
@with_kw mutable struct ProductionLineWHG
    tick::Int  = 0                         # simulation step
    bob_glues_box::Bool = false
    completed_boxes::Int = 0              
    time_alice::Matrix{Int}
    time_bob::Matrix{Int}
    q::PriorityQueue{Function, Tuple{Int,Int}}=PriorityQueue{Function, Tuple{Int,Int}}()
    time_boxes_a::Vector{Int} = Int[]
    time_boxes_b::Vector{Int} = Int[]
    log::DataFrame = DataFrame()
    storage::Int = 0   # half product storage
    max_storage::Int = 0   # maximum capacity of storage
end

function alice_assembled!(sim::ProductionLineWHG, time::Int)
    if sim.storage < sim.max_storage
        sim.storage += 1
    end
    enqueue!(sim.q, alice_take!, (time,0) )     
    enqueue!(sim.q, bob_check!, (time, 20) )     
end

function alice_take!(sim::ProductionLineWHG, time::Int)
    assembly_time = sample(sim.time_alice[:,1], Weights(sim.time_alice[:,2]))
    enqueue!(sim.q, alice_assembled!, (time+assembly_time, 10)) 
    push!(sim.time_boxes_a, assembly_time)
end

function bob_check!(sim::ProductionLineWHG, time::Int)
    if !sim.bob_glues_box && sim.storage > 0
        enqueue!(sim.q, bob_take!, (time, 20))
    end
end
function bob_take!(sim::ProductionLineWHG, time::Int)
    sim.storage -= 1
    sim.bob_glues_box = true
    bob_time = sample(sim.time_bob[:,1], Weights(sim.time_bob[:,2]))
    enqueue!(sim.q, bob_done!,(time + bob_time, 40)) 
    push!(sim.time_boxes_b, bob_time)
end
function bob_done!(sim::ProductionLineWHG, time::Int)
   sim.completed_boxes += 1
   sim.bob_glues_box = false
   enqueue!(sim.q, bob_check!, (time, 20) )
end

Random.seed!(1)
model = ProductionLineWHG(time_alice=time_alice, time_bob=time_bob, max_storage=1 )  
for _ in 1:1000
    step!(model)
end
model.log

df2 = DataFrame(
    simulate!(ProductionLineWHG(time_alice=time_alice, time_bob=time_bob, max_storage=1))  
    for n in 1:1000)

I need this production line to work even if max_storage=0.