Pre-emptive Interruptions & Options for Resuming Service¶
Pre-emptive interruptions can happen in a number of settings. In Ciw they may happen when using customer priorities, that is when a higher priority customer arrives while a lower priority customer is in service, the lower priority customer is displaced from service. They may also happen when using server schedules, when servers go off duty during a customer’s service they are displaced.
Resuming Service¶
There are a number of options of what may happen when an interrupted individual resumes service. In Ciw they can either:
Have their service resampled (
"resample"
);Restart the exact same service (
"restart"
);Continue the original service from where they left off (
"resume"
);Be re-routed to another node (
"reroute"
).
Pre-emption & Priorities¶
During non-pre-emptive priorities, customers cannot be interrupted. Therefore the lower priority customers finish their service before the higher priority customer begins their service (False
).
In order to implement pre-emptive or non-pre-emptive priorities, put the priority class mapping in a tuple with a list of the chosen pre-emption options for each node in the network. For example:
priority_classes=({'Class 0': 0, 'Class 1': 1}, [False, "resample", "restart", "resume", "reroute"])
This indicates that non-pre-emptive priorities will be used at the first node, and pre-emptive priorities will be used at the second, third and fourth nodes. Interrupted individuals will have their services resampled at the second node, they will restart their original service time at the third node, and they will continue where they left off at the fourth node.
Ciw defaults to non-pre-emptive priorities, and so the following code implies non-pre-emptive priorities:
priority_classes={'Class 0': 0, 'Class 1': 1} # non-preemptive
Note: If there are more than one lowest priority customers in service to pre-empt, then the customer who started service last will be pre-empted.
Unfinished pre-empted services are recorded as DataRecords
and so are collected along with service records with the get_all_records
method. They are distinguished by the record_type
field (services have service
record type, while pre-empted services have pre-empted service
record types).
Pre-emption & Server Schedules¶
During a non-pre-emptive schedule, customers cannot be interrupted. Therefore servers finish the current customer’s service before disappearing. This of course may mean that when new servers arrive the old servers are still there. During a pre-emptive schedule, that server will immediately stop service and leave. Whenever more servers come on duty, they will prioritise the interrupted customers and continue their service.
In order to implement pre-emptive or non-pre-emptive schedules, the ciw.Schedule
object takes in a keywords argument preemption
the chosen pre-emption option. For example:
number_of_servers=[
ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption=False), # non-preemptive
ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="resample"), # preemptive and resamples service time
ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="restart"), # preemptive and restarts origional service time
ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="resume"), # preemptive and continues services where left off
ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="reroute") # preemptive and sends the individual to another node
]
Ciw defaults to non-pre-emptive schedules, and so the following code implies a non-pre-emptive schedule:
number_of_servers=[ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100])] # non-preemptive
Re-routing Customers¶
If the "reroute"
pre-emptive option is chosen, then interrupted customers have their service cut short at the current node, and are then sent to another node. Ordinarily the next node is chosen in same way as if the customer had completed service, using the transition matrices, process based routes, or routing objects. However, it may be useful to have separate routing logic for preemptive reroutes, and a description of how to do that is given here.
Note that re-routing customers ignores queue capacities. That means that interrupted customers can be re-routed to nodes that already have full queues, nodes that would otherwise reject or block other arriving individuals; and so that node would be temporarily over-capacity.
Records of Interrupted Services¶
Interrupted services are recorded as DataRecords
and so are collected along with completed service records with the get_all_records
method. They are distinguished by the record_type
field (services have service
record type, while interrupted services have interrupted service
record types).
Note: For data records of the type interrupted service
, the service_time
field corresponds to the originally intended service time for that service, not the amount of time that the customer spent in service before being interrupted. The difference between the exit_date
and arrival_date
fields give the amount of time that customer spent in service before being interrupted.
Note: In both service
and interrupted service
record types, the waiting_time
field corresponds to the total time between the arrival_date
and the service_start_date
. Therefore this includes all previous interrupted services that customer may have experienced before this particular record’s service start date.