Learning Objectives

  • To be able to understand the process view perspective compared to the event view

  • To be able model discrete-event dynamic systems using the process view

  • To be able build process view models using the KSL

What is the Process View?

  • In the event view, we directly modeled the system state by identifying the events and specifying the state changes.

  • In the process view, the events will be implied by the action of entities within the system.

  • An entity is an object of interest that moves through the system. Entities experience processes as they experience the system.

  • A process can be thought of as a sequence of activities, where an activity is an element of the system that takes an interval of time to complete.

More About Entities

  • Entities are uniquely identifiable within the system. If there are two entities in the system, they can be distinguished by the values of their attributes.

  • Entity attributes are properties of the entity class.

    • For example, considering a product as an entity type, it may have attributes serial number, weight, category, and price.
  • Entities carry or retain these attributes and their values as they experience the system. The values of the attributes for particular entity instances might change during the operation of the system.

  • Not all information in a system is local to the entity types.

    • These types of data are called system attributes. In simulation models, this information can be modeled with properties of the enclosing model element. These properties can act as shared mutable system state for the entities.

Drive Through Pharmacy Activity Diagram

  • The activity diagram is a basic description of the process experienced by an entity.
  • Previously, we used an activity diagram to identify the arrival and end of service events.

KSL Drive Through Pharmacy Process

  • Using the activity diagram, we have an outline of the process experienced by the entity.
  • Here is the portion of the KSL code to model the process for the customers of the drive through pharmacy:
  • Notice how the code closely follows the activity diagram.
    private inner class Customer : Entity() {
        val pharmacyProcess: KSLProcess = process() {
            wip.increment()
            timeStamp = time
            val a = seize(worker)
            delay(serviceTime)
            release(a)
            timeInSystem.value = time - timeStamp
            wip.decrement()
            numCustomers.increment()
        }
    }

The KSL Elements Used for Process View Modeling

  • The Entity class is a base class that encapsulates the ability to experience processes.
  • The process() function is a very special function builder that allows for the definition of a co-routine that defines the process for the entity.
    • Coroutines are software constructs that permit the suspension and resumption of programming statements. Kotlin supports the use of coroutines for asynchronous programming.
  • The Entity class is an inner class for the ProcessModel class, which is a sub-class of ModelElement.
  • The ProcessModel class provides management for the entities that experience processes.
    • To implement the process view within the KSL you must sub-class from the ProcessModel class.
class DriveThroughPharmacy(
    parent: ModelElement,
    numPharmacists: Int = 1,
    name: String? = null
) : ProcessModel(parent, name) {
.
.
}

The Drive Through Pharmacy Code: Defining the Variables

  • Just like in the event-view, we need to have random variables and response variables defined.
  • An instance of the ResourceWithQ class defines the resource and a queue for the entities to wait.
init {
    require(numPharmacists > 0) { "The number of pharmacists must be >= 1" }
}
private val pharmacists: ResourceWithQ = ResourceWithQ(this, "Pharmacists", numPharmacists)
private var serviceTime: RandomVariable = RandomVariable(this, rSource = ExponentialRV(0.5, 2))
val serviceRV: RandomSourceCIfc
    get() = serviceTime
private var timeBetweenArrivals: RandomVariable = RandomVariable(parent, rSource = ExponentialRV(1.0, 1))
val arrivalRV: RandomSourceCIfc
    get() = timeBetweenArrivals
private val wip: TWResponse = TWResponse(this, "${this.name}:NumInSystem")
val numInSystem: TWResponseCIfc
    get() = wip
private val timeInSystem: Response = Response(this, "${this.name}:TimeInSystem")
val systemTime: ResponseCIfc
    get() = timeInSystem
private val numCustomers: Counter = Counter(this, "${this.name}:NumServed")
val numCustomersServed: CounterCIfc
    get() = numCustomers

The Drive Through Pharmacy Arrival Code

  • Just like in the event-view, we need to initialize the model using the initialize() method.
    • Here the initialize() method schedules the first arrival event.
  • The arrival() function is the event routine for the arrival event.
    • The arrival event creates a customer and activates its process.
    • Then the arrival event schedules the next arrival.
    override fun initialize() {
        schedule(this::arrival, timeBetweenArrivals)
    }

    private fun arrival(event: KSLEvent<Nothing>) {
        val c = Customer()
        activate(c.pharmacyProcess)
        schedule(this::arrival, timeBetweenArrivals)
    }

The Drive Through Pharmacy Process Code

  • The process for the customer follows the activity diagram.
  • Notice the seize() function, which attempts to use a unit of the pharmacist resource.
    • The value a returned from the seize function is called an allocation.
  • If the resource is not available, the customer instance is suspended while waiting in a queue.
  • During the delay, the process routine is again suspended until the timed delay is completed.
  • When the entity is done with the resource it releases it using the release() function.
    • The allocation is used to release the corresponding seize.
  • Response statistics can be easily collected within the process.
    private inner class Customer : Entity() {
        val pharmacyProcess: KSLProcess = process() {
            wip.increment()
            timeStamp = time
            val a = seize(pharmacists)
            delay(serviceTime)
            release(a)
            timeInSystem.value = time - timeStamp
            wip.decrement()
            numCustomers.increment()
        }
    }
}

Key Concepts in the KSL Pharmacy Code

  • Sub-class from ProcessModel to have access to entity and process constructs.
  • Use the ResourceWithQ class to define the resource to be used within the process.
  • Sub-class Entity to define the Customer entity class and its process routine.
  • In the arrival event, a customer is created and its process is activated via the activate() function, which is available only within sub-classes of ProcessModel
  • When an entity is activated, it starts the denoted process. This is like the process routine being called, sort of like a function.
    • Then the statements within the process get executed (sequentially) until a suspending function occurs.
    • If the execution is suspended, the entity waits until it is resumed and then continues at the next line of code. This is how co-routines operate. This is sometimes called a continuation.
    • Use the seize(), delay(), and release() functions of the KSLProcess to work with resources via shared mutable state.
  • The seize() and delay() functions are suspending functions, which can only be called within a coroutine context.

Understanding KSL Process Modeling

  • It is critical to understand that

    1. there are many entities created via the arrival method,
    2. all the entities experience the same process, and
    3. the entities may all be at different points of their processes at different times.
  • Since many customers are active at the same time (in a pseudo-parallelism) they compete for the pharmacist. This causes queueing.

  • This process view depends on shared state.

  • In this model, the primary shared state is via the resource.

Results from Running the Pharmacy Model

  • These are exactly the same results as obtained with the event-view.
Half-Width Statistical Summary Report - Confidence Level (95.000)% 

Name                                     Count        Average      Half-Width 
------------------------------------------------------------------------------------ 
NumBusy                                    30          0.5035          0.0060 
# in System                                30          1.0060          0.0271 
System Time                                30          6.0001          0.1441 
PharmacyQ:NumInQ                           30          0.5025          0.0222 
PharmacyQ:TimeInQ                          30          2.9961          0.1235 
SysTime > 4.0 minutes                      30          0.5136          0.0071 
Num Served                                 30       2513.2667         17.6883 
----------------------------------------------------------------------------------------- 

Entity States

  • The KSL process model works because it has clearly defined states for how entities interact within a process.
  • The key states are Created, Scheduled, Active, Suspended, and Process Ended.
    • The Suspended state has 6 defined sub-states.

Entity State Definitions

  • CreatedState - The entity is placed into this state when it is created. From the created state, the entity can be scheduled to be active.
    • The activate() function of the entity causes the entity to be scheduled to be activated.
  • Scheduled - The scheduled state indicates that the entity is associated with an event that is pending to occur in the event calendar. The entity is scheduled to be active at some future time. The underlying process associated with the entity is suspended.
    • The delay() function will place the entity in the scheduled state.
  • Active - This is the state that indicates that the entity is executing an underlying process. It is executing non-suspending code within its process. It is the active entity. From the active state, the entity can be suspended for a number of reasons, each mapped to various states.
    • The entity becomes active when its process is resumed.
  • WaitingForResource - This state indicates that the entity’s process is suspended because the entity is waiting for units of a resource.
    • The seize() function can place the entity into this state.

Entity State Definitions

  • WaitingForSignal - This state indicates that the entity’s process is suspended because the entity is waiting on an arbitrary signal to be sent.

  • BlockedSending - This state indicates that the entity’s process is suspended because the entity is trying to send an item via a shared blocking queue and there is not space for the item in the queue. Blocking queues can be used to communicate between processes.

  • BlockedReceiving - This state indicates that the entity’s process is suspended because the entity is trying to receive items from a blocking queue and there are no items to receive. This is the other end of the communication channel formed by a blocking queue.

  • InHoldQueue - This state indicates that the entity’s process is suspended because the entity is an arbitrary queue that holds entities until they are removed and re-activated.

  • WaitForProcess - An entity may activate another process. This state indicates that the entity’s process is suspended because the entity is waiting for the process to complete before proceeding.

Process Coroutine States

  • The entity states are mapped onto the lower level coroutines via an internal inner class (ProcessCoroutine). This class defines the legal states of the coroutine.

Process Coroutine State Definitions

  • Created - The process coroutine is placed in this state when it is instantiated.
    • When created the coroutine executes until it reaches its first suspension point.
  • Running - The coroutine is running after it is started. This occurs when the entity activates the associated process. Processes are started by scheduling an event that invokes the coroutine code at the appropriate simulated time.
    • The entity moves through its process and when the entity is between suspension points the process is considered to be in the running state.
  • Suspended - The underlying process coroutine is suspended using Kotlin’s coroutine suspension functionality. Suspension is mapped to the various suspension states associated with an entity.
  • Completed - The process coroutine has exited normally from the process routine or reached the end of the process routine. Once completed the coroutine is finished.
  • Terminated - The process coroutine has exited abnormally via an error or exception or the user has directly terminated the process. Once terminated the coroutine is finished.

Overview of KSL Process Modeling Constructs

  • EntityGenerator is like an EventGenerator but defined to create and activate entities.
  • ResourceWithQ is a shared resource with specified capacity that can be seized and released.
  • HoldQueue is a shared queue that can hold entities until they are removed. The entities that enter the hold queue are suspended.
  • Signal is a class that uses an instance of a HoldQueue to hold entities until they are notified to resume via the index of their rank within the queue.
  • BlockingQueue a blocking queue can be used to assist with communication between two processes.
    • Blocking queues can block on sending or on receiving.
    • The typical use is to block when trying to dequeue an item from the queue when the queue is empty or if you try to enqueue an item and the queue is full.
    • A process trying to dequeue from an empty queue is blocked until some other process inserts an item into the queue.
    • A process trying to enqueue an item in a full queue is blocked until some other process makes space in the queue, either by dequeuing one or more items or clearing the queue completely.
  • The waitFor(process: KSLProcess) suspending function activates the named process and suspends the current process until the activated process completes.

Modeling a STEM Career Fair Mixer

In this example, we model the operation of a STEM Career Fair mixer during a six-hour time period. The purpose of the example is to illustrate the following concepts:

  • Probabilistic flow of entities

  • Collecting statistics on observational (tally) and time-persistent data using the KSL responses

  • Using the seize(), delay(), and release() functions of the KSLProcessBuilder class

STEM Career Fair Example: Conceptualizing the System

STEM Career Fair Description

  • Students arrive to a STEM career mixer event according to a Poisson process at a rate of 0.5 student per minute. The students first go to the name tag station, where it takes between 15 and 45 seconds uniformly distributed to write their name and affix the tag to themselves. We assume that there is plenty of space at the tag station, as well as plenty of tags and markers, such that a queue never forms.

  • After getting a name tag, 50% of the students wander aimlessly around, chatting and laughing with their friends until they get tired of wandering. The time for aimless students to wander around is triangularly distributed with a minimum of 15 minutes, a most likely value of 20 minutes, and a maximum value of 45 minutes. After wandering aimlessly, 90% decide to buckle down and visit companies and the remaining 10% just are too tired or timid and just leave. Those that decide to buckle down visit the MalWart station and then the JHBunt station as described next.

STEM Career Fair Description

  • The remaining 50% of the original, newly arriving students (call them non-aimless students), first visit the MalWart company station where there are 2 recruiters taking resumes and chatting with applicants.
  • At the MalWart station, the student waits in a single line (first come first served) for 1 of the 2 recruiters. After getting 1 of the 2 recruiters, the student and recruiter chat about the opportunities at MalWart. The time that the student and recruiter interact is exponentially distributed with a mean of 3 minutes.
  • After visiting the MalWart station, the student moves to the JHBunt company station, which is staffed by 3 recruiters. Again, the students form a single line and pick the next available recruiter. The time that the student and recruiter interact at the JHBunt station is also exponentially distribution, but with a mean of 6 minutes.
  • After visiting the JHBunt station, the student departs the mixer.

Identify the Entities, Activities, and Resources

Entity Type Activity Resource Used
Student (all) time to affix a name tag ~ UNIF(15, 45) seconds None
Student (wanderer) Wandering time ~ TRIA(15, 15, 45) minutes None
Student (not timid) Talk with MalWart ~ EXPO(3) minutes 1 of 2 MalWart recruiters
Student (not timid) Talk with JHBunt ~ EXPO(6) minutes 1 of 3 JHBunt recruiters

Draw an Activity Diagram

Implementing the Model: Sub-class from ProcessModel

  • Define the necessary random variables and the responses
class StemFairMixer(parent: ModelElement, name: String? = null) : 
  ProcessModel(parent, name) {
    private val myTBArrivals: RVariableIfc = ExponentialRV(2.0, 1)
    private val myNameTagTimeRV = RandomVariable(this, 
      UniformRV((15.0 / 60.0), (45.0 / 60.0), 2))
    private val myWanderingTimeRV = RandomVariable(this,
      TriangularRV(15.0, 20.0, 45.0, 3))
    private val myTalkWithJHBunt = RandomVariable(this, ExponentialRV(6.0, 4))
    private val myTalkWithMalMart = RandomVariable(this, ExponentialRV(3.0, 5))
    private val myDecideToWander = RandomVariable(this, BernoulliRV(0.5, 6))
    private val myDecideToLeave = RandomVariable(this, BernoulliRV(0.1, 7))
    private val myOverallSystemTime = Response(this, "OverallSystemTime")
    private val mySystemTimeNW = Response(this, "NonWanderSystemTime")
    private val mySystemTimeW = Response(this, "WanderSystemTime")
    private val mySystemTimeL = Response(this, "LeaverSystemTime")
    private val myNumInSystem = TWResponse(this, "NumInSystem")

Implementing the Model: Add Process View Elements

  • Define the shared resources for the recruiters.

  • Define the entity generator for creating and activating the students.

class StemFairMixer(parent: ModelElement, name: String? = null) :
  ProcessModel(parent, name) {
.
.
    private val myJHBuntRecruiters: ResourceWithQ 
        = ResourceWithQ(this, capacity = 3, name = "JHBuntR")
        
    private val myMalWartRecruiters: ResourceWithQ
        = ResourceWithQ(this, capacity = 2, name = "MalWartR")
        
    private val generator = EntityGenerator(::Student, myTBArrivals,
        myTBArrivals)

Implementing the Model: Define the Student Entity

  • Special return syntax is needed within a process.
    private inner class Student : Entity() {
        private val isWanderer = myDecideToWander.value.toBoolean()
        private val isLeaver = myDecideToLeave.value.toBoolean()
        val stemFairProcess = process(isDefaultProcess = true) {
            myNumInSystem.increment()
            delay(myNameTagTimeRV)
            if (isWanderer) {
                delay(myWanderingTimeRV)
                if (isLeaver) {
                    departMixer(this@Student)
                    return@process
                }
            }
.
.
        }

Implementing the Model: Define the Student Entity

  • This process follows closely the activity diagram.
    private inner class Student : Entity() {
.
.
.
            val mw = seize(myMalWartRecruiters)
            delay(myTalkWithMalMart)
            release(mw)
            val jhb = seize(myJHBuntRecruiters)
            delay(myTalkWithJHBunt)
            release(jhb)
            departMixer(this@Student)
        }

Implementing the Model: Capturing Final Statistics

  • A Kotlin function was implemented to capture statistics on the students as they depart the system.
        private fun departMixer(departingStudent: Student) {
            myNumInSystem.decrement()
            val st = time - departingStudent.createTime
            myOverallSystemTime.value = st
            if (isWanderer) {
                mySystemTimeW.value = st
                if (isLeaver) {
                    mySystemTimeL.value = st
                }
            } else {
                mySystemTimeNW.value = st
            }
        }
    }

Selected STEM Fair Results

Half-Width Statistical Summary Report - Confidence Level (95.000)% 

Name                         Count        Average      Half-Width 
------------------------------------------------------------------ 
JHBuntR:BusyUnits            400           2.5219          0.0196 
JHBuntR:Util                 400           0.8406          0.0065 
JHBuntR:Q:NumInQ             400           4.9292          0.3765 
JHBuntR:Q:TimeInQ            400          10.5192          0.7647 
MalWartR:BusyUnits           400           1.3565          0.0138 
MalWartR:Util                400           0.6783          0.0069 
MalWartR:Q:NumInQ            400           1.3083          0.1109 
MalWartR:Q:TimeInQ           400           2.7696          0.2162 
OverallSystemTime            400          34.0890          0.8409 
NonWanderSystemTime          400          22.1052          0.8451 
WanderSystemTime             400          47.1148          0.8315 
LeaverSystemTime             400          27.0520          0.2334 
NumInSystem                  400          16.7704          0.4829 
-----------------------------------------------------------------

Summary of Implementation Issues

  • Used time-persistent (TWReponse) and tally response (Response) variables to collect required statistics.
  • Used random variables RandomVariable to model the time delays and to assign probabilistic student type.
  • The delay() suspending function was used to model the name tag activity, the wandering time, and the time spent with the recruiters.
  • The seize() and release() functions were used to interact with the recruiter resources.
  • Special, return@ syntax was used to exit the process routine.
  • The Student class constructor was supplied to the entity generator via the ::Student syntax.

The Tie-Dye T-Shirt System

  • Suppose production orders for tie-dye T-shirts arrive to a production facility according to a Poisson process with a mean rate of 1 per hour.

  • There are two basic psychedelic designs involving either red or blue dye. For some reason the blue shirts are a little more popular than the red shirts so that when an order arrives about 70% of the time it is for the blue dye designs. In addition, there are two different package sizes for the shirts, 3 and 5 units.

  • There is a 25% chance that the order will be for a package size of 5 and a 75% chance that the order will be for a package size of 3. Each of the shirts must be individually hand made to the customer’s order design specifications.

  • The time to produce a shirt (of either color) is uniformly distributed within the range of 15 to 25 minutes.

The Tie-Dye T-Shirt System

  • There are currently two workers who are setup to make either shirt. When an order arrives to the facility, its type (red or blue) is determined and the pack size is determined. Then, the appropriate number of white (un-dyed) shirts are sent to the shirt makers with a note pinned to the shirt indicating the customer order, its basic design, and the pack size for the order.

  • Meanwhile, the paperwork for the order is processed and a customized packaging letter and box is prepared to hold the order. It takes another worker between 8 to 10 minutes to make the box and print a custom thank you note.

  • After the packaging is made it waits prior to final inspection for the shirts associated with the order.

  • After the shirts are combined with the packaging, they are inspected by the packaging worker which is distributed according to a triangular distribution with a minimum of 5 minutes, a most likely value of 10 minutes, and a maximum value of 15 minutes.

  • Finally, the boxed customer order is sent to shipping.

The Tie-Dye T-Shirt Activity Diagram

  • Notice how there are actually two entities: orders and shirts
  • Notice also how the packager is shared between two activities

Implementing the Tie-Dye T-Shirt Model: Sub-class from ProcessModel

  • Define the random variables and responses
class TieDyeTShirts(parent: ModelElement, theName: String? = null) : 
  ProcessModel(parent, theName) {
    private val myTBOrders: RVariableIfc = ExponentialRV(60.0)
    private val myType: RVariableIfc = DEmpiricalRV(doubleArrayOf(1.0, 2.0), 
      doubleArrayOf(0.7, 1.0))
    private val mySize: RVariableIfc = DEmpiricalRV(doubleArrayOf(3.0, 5.0), 
      doubleArrayOf(0.75, 1.0))
    private val myOrderSize = RandomVariable(this, mySize)
    private val myOrderType = RandomVariable(this, myType)
    private val myShirtMakingTime = RandomVariable(this, UniformRV(15.0, 25.0))
    private val myPaperWorkTime = RandomVariable(this, UniformRV(8.0, 10.0))
    private val myPackagingTime = RandomVariable(this, TriangularRV(5.0, 10.0, 15.0))
    private val mySystemTime = Response(this, "System Time")
    private val myNumInSystem = TWResponse(this, "Num in System")

Implementing the Tie-Dye T-Shirt Model: Process View Constructs

  • Note the use of a ResourceWithQ to model the shirt makers
  • Notice that we use a RequestQ to represent the queue for the orders.
    • A RequestQ is a subclass of the Queue class that is specifically designed to work with seize requests for resources.
  • The seize() suspend function allows both the specification of the resource being seized and the queue that will hold the entity if the seize request is not immediately filled. There are two queues involving the use of the packager 1) to hold the in-process orders and 2) the completed orders.
    private val myShirtMakers: ResourceWithQ = ResourceWithQ(this, capacity = 2,
        name = "ShirtMakers_R")
    private val myOrderQ : RequestQ = RequestQ(this, name = "OrderQ")
    private val myPackager: ResourceWithQ = ResourceWithQ(this, "Packager_R")
    private val generator = EntityGenerator(::Order, myTBOrders, myTBOrders)
    private val completedShirtQ: BlockingQueue<Shirt> = BlockingQueue(this, 
        name = "Completed Shirt Q")

Implementing the Tie-Dye T-Shirt Model: The Order Process

  • Regular flow of control constructs (e.g. for-loop) can be used in a process routine.
  • A process can create and activate other entity processes.
    private inner class Order: Entity() {
        val type: Int = myOrderType.value.toInt() 
        val size: Int = myOrderSize.value.toInt()
        var completedShirts : List<Shirt> = emptyList()

        val orderMaking : KSLProcess = process("Order Making") {
            myNumInSystem.increment()
            for(i in 1..size){
                val shirt = Shirt(this@Order.id)
                activate(shirt.shirtMaking)
            }
            ....
        }
    }

Implementing the Tie-Dye T-Shirt Model: The Order Process

  • Note the signature of the seize() method, which specifies the queue for waiting orders.
  • An instance of a BlockingQueue holds completed shirts and communicates that they are ready.
  • The property orderNum is used to identify, for the shirt, which order created it.
    private inner class Order: Entity() {
 ...
      var a = seize(myPackager, queue = myOrderQ)
      delay(myPaperWorkTime)
      release(a)
      // wait for shirts
      completedShirts = waitForItems(completedShirtQ, size, {it.orderNum == this@Order.id})
      a = seize(myPackager)
      delay(myPackagingTime)
      release(a)
      myNumInSystem.decrement()
      mySystemTime.value = time - this@Order.createTime
    }
 }

Implementing the Tie-Dye T-Shirt Model: The Shirt Making Process

  • The shirt making process is constructed based on a different entity that represents what happens to a shirt.
  • The blocking queue that was defined as part of the process model is used to send a reference to the shirt to the channel queue that connects the shirt process with the ordering process,
    • As the shirts are made, they are sent to the channel. When the correct number of shirts for the order are made the waiting order can pull them from the channel and continue with its process.
    private inner class Shirt(val orderNum: Long): Entity() {
        val shirtMaking: KSLProcess = process( "Shirt Making"){
            val a = seize(myShirtMakers)
            delay(myShirtMakingTime)
            release(a)
            // send to orders
            send(this@Shirt, completedShirtQ)
        }
    }

Selected Tie-Dye T-Shirt Model Results

Half-Width Statistical Summary Report - Confidence Level (95.000)% 

Name                                  Count        Average     Half-Width 
-------------------------------------------------------------------------
ShirtMakers_R:BusyUnits               30           1.0997          0.1407 
ShirtMakers_R:Util                    30           0.5499          0.0703 
ShirtMakers_R:Q:NumInQ                30           1.6911          0.6280 
ShirtMakers_R:Q:TimeInQ               30          23.3987          5.8618 
Packager_R:BusyUnits                  30           0.2968          0.0376 
Packager_R:Util                       30           0.2968          0.0376 
Packager_R:Q:NumInQ                   30           0.0424          0.0248 
Packager_R:Q:TimeInQ                  30           1.0717          0.5204 
System Time                           30          66.9589          6.3726 
Num in System                         30           1.1446          0.2502 
Completed Shirt Q:RequestQ:NumInQ     30           0.8054          0.1983 
Completed Shirt Q:RequestQ:TimeInQ    30          46.1496          5.8560 
Completed Shirt Q:ChannelQ:NumInQ     30           0.8047          0.1134 
Completed Shirt Q:ChannelQ:TimeInQ    30          14.8315          0.8088 
-------------------------------------------------------------------------

Summary of New Concepts

  • The process view facilitates a linear flow of the sequence of events that an entity experiences.
  • Kotlin coroutines were used to implement the process view.
  • New constructs to assist with process modeling include:
    • ResourceWithQ - models both a resource and a queue to hold waiting entities
    • RequestQ - holds entities that are requesting units of a resource
    • Resource - models a set of units that may be used by entities
    • BlockingQueue - facilitates communication between two processes
    • EntityGenerator - facilitates creating entities according to a timed pattern
    • seize(), delay(), waitForItems() and send() are suspending functions
  • Implement the process view by sub-classing from ProcessModel and defining processes via sub-classes of the Entity class.
⌂ Index