I also discovered that the crash only occurs
after the batch step on attempting to select or seize the resource that is interleaved with the batch tool (i.e., "50547" in my original post). During debugging R crashes immediately after stepping out of the bolded select() step below:
interleaved_traj <- simmer::trajectory() |>
simmer::log_('Entering interleaved traj...', level = 3) |>
# --- Select and seize the operator token ---
simmer::select(
\() {
token_list
},
policy = 'first-available',
tag = 'select_token'
) |>
simmer::log_(
\() {
sprintf('Selected token %s', simmer::get_selected(env))
},
level = 3
) |>
# Need an unfinished handler here in case the operator's shift ends
# before transition can be completed
simmer::handle_unfinished(
handler = simmer::trajectory() |>
simmer::log_(
'Unfinished transition, finding new operator...',
level = 2
) |>
simmer::rollback(target = 'select_token')
) |>
# Only wait 1 hour before looking for another operator to prevent
# staying stuck in the same queue for the operator's entire shift
simmer::renege_in(
t = 1.0,
out = simmer::trajectory() |>
simmer::log_(
\() {
'Reneging & looking for new operator.'
},
level = 3
) |>
simmer::rollback(target = 'select_token'),
keep_seized = TRUE
) |>
simmer::seize_selected() |>
simmer::renege_abort() |>
simmer::log_(
\() {
sprintf('Seized token %s', simmer::get_selected(env))
},
level = 3
) |>
# --- Select and release the equipment ---
# If equipment was already released and arrival is in a rollback trajectory
# (i.e., either unfinished or reneged), then skip over the equipment release
# step
simmer::branch(
continue = TRUE,
option = \() {
seized_resources <- res_df$EquipmentNbr[
as.logical(simmer::get_seized(env, res_df$EquipmentNbr))
]
eqp_name <- seized_resources[
!stringr::str_detect(seized_resources, 'Operator')
]
if (length(eqp_name) > 0) {
1
} else {
0
}
},
simmer::trajectory() |>
simmer::select(
\() {
if (simmer::now(env) > t_break) {
browser()
}
seized_resources <- res_df$EquipmentNbr[
as.logical(simmer::get_seized(env, res_df$EquipmentNbr))
]
eqp_name <- seized_resources[
!stringr::str_detect(seized_resources, 'Operator')
]
eqp_name
}
) |>
simmer::log_(
\() {
if (simmer::now(env) > t_break) {
browser()
}
sprintf('Releasing eqp %s', simmer::get_selected(env))
},
level = 3
) |>
simmer::release_selected()
) |>
# --- Select and seize the interleaved operator ---
simmer::select(
\() {
if (simmer::now(env) > t_break) {
browser()
}
seized_resources <- res_df$EquipmentNbr[
as.logical(simmer::get_seized(env, res_df$EquipmentNbr))
]
token_name <- seized_resources[
stringr::str_detect(seized_resources, 'Operator')
]
# Get the operator name from the token name
operator_name <- stringr::str_remove(token_name, '_token')
operator_name
}
) |>
simmer::seize_selected() |>
simmer::log_(
\() {
sprintf('Seized interleaved op %s', simmer::get_selected(env))
},
level = 3
) |>
# --- Select and release the operator token ---
simmer::select(\() {
selected_resources <- res_df$EquipmentNbr[
as.logical(simmer::get_seized(env, res_df$EquipmentNbr))
]
token_name <- selected_resources[
stringr::str_detect(selected_resources, '_token')
]
token_name
}
) |>
simmer::release_selected() |>
# --- Timeout with the operator and release ---
simmer::select(
\() {
selected_resources <- res_df$EquipmentNbr[
as.logical(simmer::get_seized(env, res_df$EquipmentNbr))
]
operator_name <- selected_resources[
stringr::str_detect(selected_resources, 'Operator')
]
operator_name
}
) |>
simmer::log_(
\() {
sprintf('Transitioning with %s', simmer::get_selected(env))
},
level = 3
) |>
# If a batched lot operation, we need to separate the lots
simmer::branch(
\() {
if (stringr::str_detect(simmer::get_name(env), 'batch')) {
1
} else {
0
}
},
simmer::trajectory() |>
simmer::log_('Separating batch') |>
simmer::separate(),
continue = TRUE
) |>
simmer::timeout_from_attribute('transition_time') |>
simmer::release_selected_all()