Search code examples
rsimulation

R Simmer check the max wait time when joining queue


I'm hoping this is an easy question! I can see that there is a function get_queue_count which is almost what I need, but I don't need the number in the queue, I need to know the max time spent in the queue by any individual. I can then send the customers down another trajectory if the max queue time is over a variable.

Any help, as always, greatly appreciated!


Solution

  • Creating a custom function solved this. Admittedly I need to clean this and I'm sure someone could make it a lot faster but there we go.

    fn_queue_time <- function() {
    qt <- sim %>%
    get_mon_attributes() %>%
    filter(key == "q_start" | key == "q_end") %>%
    group_by(name) %>%
    mutate(count = n()) %>%
    filter(count == 1) %>%
    pivot_wider(id_cols = name, names_from= key, values_from = time) %>%
    mutate(q = simmer::now(sim) - q_start) %>%
    ungroup() %>%
    summarise(m = max(q)) %>%
    pull()
    }
    
    arrive <- c(1:5)
    
    traj <- trajectory("traj") %>%
    log_("arrive") %>%
    set_attribute(keys = "q_start", values = function() {now(sim)}) %>%
    log_(function() {paste("Q time: ", fn_queue_time())}) %>%
    branch(function() ifelse(fn_queue_time() >= 5, 1, 2),
    continue = F,
    trajectory() %>%
    log_("q too long, offered alternative") %>%
    
    renege_in(5,
    out = trajectory() %>%
    log_("alternative accepted") %>% set_attribute(keys = "q_end", values = function() {now(sim)}) %>%
    set_attribute(keys = "alternative accepted", values = function() {now(sim)})
    ) %>%
    seize("resource") %>%
    log_("service") %>%
    renege_abort() %>%
    set_attribute(keys = "q_end", values = function() {now(sim)}) %>%
    timeout(10) %>%
    release("resource"),
    trajectory() %>%
    log_("norm") %>%
    renege_in(5, out = trajectory() %>%
    log_("reneg") %>% set_attribute(keys = "q_end", values = function() {now(sim)}) %>%
    set_attribute(keys = "reneg", values =function({now(sim)})) %>%
    seize("resource") %>%
    log_("service") %>%
    renege_abort() %>%
    set_attribute(keys = "q_end", values = function() {now(sim)}) %>%
    timeout(10) %>%
    log_("service end") %>%
    release("resource"))
    
    sim <- simmer("sim") %>%
    add_generator("cust",traj, at(arrive), mon = 2) %>%
    add_resource("resource", 1)
    
    
    sim %>%
    run(until = 800)