-
Notifications
You must be signed in to change notification settings - Fork 1
4. Worker
Workers are the actual executors and processors doing the work, whereas a Processor represents a processing step or a workstation where the Workers process the working packages (Bundles). Multiple Workers can be assigned to a a Processor (1 to N relationship) for doing work. Commonly, the incoming work packages (Bundles) are buffered in queues (see Simple Processor), until they are grabbed and processed by the assigned Workers. Each Worker is triggered by the clock signal (commonly forwarded by the underlying Processor by calling the Update(long) method) and maintains its own state. There are four states defined:
- Idle: The Worker is idling and waits for the next Bundle in the input buffer.
- Busy: The Worker is currently processing one or multiple Bundles (the number depends on the implementation).
-
Paused: The Worker has been manually paused by calling
Pause(). - Blocked: The Worker cannot continue to process one or multiple Bundles due to missing resources.
There are two methods
Continue() and Pause() for changing the state from outside of the class. Pause() pauses the current work and the Worker would only continue to process the current Bundle(s) or to grab new Bundles as soon as Continue() is called. All other states are maintained by each Worker itself. As a result, a Worker does not need to be supplied with work if the processing of a Bundle has been finished, but automatically checks the input buffer for further Bundles with each Update(long). Additionally, each instance of Worker should have its own identifier.The following section introduces two special types of Workers as well as a generic (abstract) Worker the special types of Worker base on.
A Delay Worker processes a Bundle without modifying it. This means that the Bundle is kept unaltered, but the processing steps takes a predefined period of time (ticks). Hence, it is called Delay Worker, because the Worker just delays the Bundle. Per processing step only one Bundle is processed by one Delay Worker (but multiple Workers can be assigned to Processor for parallel processing). There are two ways how the duration for processing one Bundle can be defined:
-
Statically:
The duration is defined with each Worker and the same for all Bundles being processed by this specific instance of Worker. -
Dynamically:
The duration is defined over the header of an incoming Bundle. The Worker reads this header and applies the stored duration. Hence, the duration is dynamic for each instance of Bundle depending on the set header value. Use an Abstract or Static Attribute Setter to set the duration header before passing the Bundle to the underlying Processor.
Regardless of these two ways, it can be specified (with each Worker) whether the duration value is applied for the whole Bundle (i.e. duration per Bundle) or multiplied by the number for underlying Entites (i.e. duration per Entity).
Example:
It takes 500 ticks to process a Bundle with 10 Entites if the duration is set to 50 ticks and the duration is applied for one Entity. After 500 ticks the whole Bundle including the 10 Entites is passed to the next step and the Workers takes the next Bundle out of the input buffer or goes to idle if there is no further work.
Usage:
Delay Workers can be used for simulation in which the duration of a pure material flow without any changes of the material/simulation production process is measured and analyzed.
The Transport Worker behaves similarly to the Delay Worker and represents a Worker transporting Bundles from one step to another (where the transport step is considered as a separate step, not a Connector). For a realistic simulation this means, that two durations must be considered. A transport route consists of two components, the way from source to target (away) having the Bundle loaded and the way back to the source, before a new Bundle can be loaded. Since Transport Worker is only a representation and does not actually move between the steps (the Worker is permanently assigned to the transport processing step), it is necessary that a Bundle is passed to the next step after the away-duration has been elapsed, but then the Transport Worker has to wait for a second period of time (way back-duration) until the next Bundle can be loaded and processed.
In comparison to the Delay Worker, it is possible to define these two duration statically with each Transport Worker instance or dynamically per Bundle header, but it is not possible to apply the duration per Entity.
The Abstract Worker represents a generic Worker and can be implemented based on the needs for the simulation. The abstract class Worker cannot be instantiated and is the base for Delay Worker and Transport Worker.
The classes TransportWorker and DelayWorker extend from the base but abstract class Worker (representing the abstract Worker). The abstract Worker class has attributes for storing the state of the Worker, its identifier and for referencing the underlying Processor. The latter is needed for taking Bundles out of the input pipe of the Processor (by calling Host.Take()) or pass a processed Bundle to the successor of the Processor (by calling Host.Sucessor.In(Bundle)). These attributes are encapsulated by property methods (getter and setter) and methods for changing the state manually (Pause() and Continue()).
The class DelayWorker extends the abstract class Worker by adding attributes for the specified duration (ticks) or the header name where the duration can be read from and flags indicating where the duration should be taken from (statically or dynamically) and whether the duration should be applied per Bundle or per Entity (for details see chapter X). These attributes are encapsulated by property methods (getter) and two special methods for setting the duration:
The method SetDuration is overloaded and exists with two types of parameter lists. With the method SetDuration(long, bool) the duration can be set statically where the first parameter is the duration value (ticks) and the second parameter is the flag indicating whether the duration should be applied per Bundle or per Entity. The second method SetDuration(string, bool) does the same but sets the duration dynamically by specifying the name of the header as the first parameter where the duration can be read from.
Furthermore, the abstract methods Update(long), Count() and EntityCount() are implemented together with attributes for storing the Bundle which is currently processed as well as an internal counter for maintaining the progress of processing the current Bundle.
The class TransportWorker has similar attributes and methods like DelayWorker and also extends from Worker. Nevertheless, it defines two types of durations stored in two attributes, but both durations are applied per Bundle (the option that the durations are applied per Entity are not given). Durations can be read from header values, hence there are four overloaded methods for setting the duration.