5.1.1. Implementation with OESjs

The JavaScript-based simulator OESjs-Core2 implements the Object Event Simulation (OES) paradigm, and, consequently, allows a straight-forward coding of OE class models and DPMN process models.

Implementing the Information Design Model

For implementing the OE class design model with OESjs-Core2, we have to code all object types, event types and activity types specified in the model in the form of JavaScript classes extending the respective OESjs framework classes oBJECT, eVENT and aCTIVITY. We start with the object type OrderTaker shown in the following diagram:

???

The OrderTaker object class can be coded in the following way:

class OrderTaker extends oBJECT {
  constructor({ id, name, status}) {
    super( id, name);
    this.status = status;
  }
}

All object classes inherit an id attribute and a name attribute from the pre-defined OES foundation class oBJECT. Since order takers are resource objects, we need to define a status property having the pre-defined enumeration data type ResourceStatusEL as its range.

The other object classes (PizzaMaker, Oven and Scooter) are coded in the same way.

We next show how to code the event type OrderCall depicted in the following diagram:

???

The OrderCall event class is coded in the following way:

class OrderCall extends eVENT {
  constructor({ occTime, delay}) {
    super({occTime, delay});
  }
  createNextEvent() {
    return new OrderCall({delay: OrderCall.recurrence()});
  }
  static recurrence() {
    var hour = Math.floor(sim.time / 60);
    return rand.exponential( OrderCall.arrivalRates[hour]);
  }
}
// arrival rates per minute (for a daily operation for 5 hours)
OrderCall.arrivalRates = [1/6, 1/0.66, 1/1.5, 1/6, 1/12];

All event classes inherit an occTime attribute and a delay attribute from the pre-defined OES foundation class eVENT. Any event in OES can be created either with a value for the attribute occTime (standing for occurrence time) or with a value for the attribute delay. In the latter case, the event's occurrence time is automatically derived by adding the value of delay to the current simulation time.

Notice how the time-varying recurrence rates (representing order arrival rates) are implemented in the recurrence function: by first computing the current hour, which is then used as an index for accessing the corresponding element of the OrderCall.arrivalRates array.

Finally, we show how to code the activity type TakeOrder depicted in the following diagram:

???

The TakeOrder activity class is coded in the following way:

class TakeOrder extends aCTIVITY {
  constructor({id, startTime, duration}={}) {
    super({id, startTime, duration});
  }
  static duration() {
    return rand.uniform( 1, 4);
  }
  static waitingTimeout() {
    return rand.uniformInt( 3, 6);
  }
}
TakeOrder.resourceRoles = {
  "orderTaker": {range: OrderTaker}
}

All activity classes inherit the attributes id, startTime and duration from the pre-defined OES foundation class aCTIVITY. When an activity is created as a JS object during a simulation run, the value of its duration property is obtained by invoking the duration() function defined as a class-level ("static") function for its activity class. These activity duration functions typically implement a random variable by invoking a random variate sampling function, such as rand.triangular(30,50,40), which samples from the triangular probability distribution function (with min/max=30/50 and mode=40).

Notice how the resource role association between TakeOrder and OrderTaker, which defines the resource reference property TakeOrder::orderTaker, is coded by a corresponding entry in the map-valued class-level property resourceRoles.

Implementing the Process Design Model

The following process design model specifies six types of events: order call events, take order waiting timeouts, lost order events, take order activities, make pizza activities, and deliver pizza activities:

???

A DPMN process design model can be decomposed into a set of event rule design models, one for each type of event specified in the design model. Since the LostOrder event and the DeliverPizza activity do not have any effects, we only need four event rules.

1 The OrderCall event rule

Starting with the following OrderCall event rule design model, we show how the event rules specified by each of these event rule design models can be coded.

???

The OrderCall event rule does not define any state changes of affected objects, but only the resource-dependent scheduling of a TakeOrder activity, which is coded with the following OESjs statement:

OrderCall.successorActivity = "TakeOrder";
2 The TakeOrder Waiting Timeout event rule
???

The TakeOrder Waiting Timeout event rule only schedules the immediate occurrence of a LostOrder event, which is coded with the following OESjs event routine within the TakeOrder activity class:

onWaitingTimeout() {
  var followupEvents=[];
  followupEvents.push( new LostOrder());
  return followupEvents;
}
3 The TakeOrder event rule

Since activities are composite events, we also have event rules for them. These rules are triggered when an activity completes, that is, by the corresponding activity end events.

???

The TakeOrder event rule only takes care of the resource-dependent scheduling of a MakePizza activity, which is coded with the following OESjs statement:

TakeOrder.successorActivity = "MakePizza";
4 The MakePizza event rule
???

The MakePizza event rule only takes care of the resource-dependent scheduling of a DeliverPizza activity, which is coded with the following OESjs statement:

MakePizza.successorActivity = "DeliverPizza";