Class Service<T>

java.lang.Object
com.amalgamasimulation.service.Service<T>
Type Parameters:
T - type of units served
Direct Known Subclasses:
FixedCapacityService, ManualService

public abstract class Service<T> extends Object
Service is a class that models a queue of units waiting for service and the servicing of units itself. One or several units can be served simultaneously. Service automatically keeps track of the queue of units waiting for service and decides what unit must be served next.

Units waiting for service can be retrieved by getWaitingUnits() method, units being served can be retrieved be getServicedUnits() method.

A typical use case of this class can include the following steps:

  1. A request for service of some unit can be placed by calling placeRequest(Object, Consumer) method. The second argument of this method is a handler called when the unit starts being served.
  2. After a request for service of a unit is placed and before the unit starts being served, the request can be canceled by calling cancelRequest(Object) method.
  3. The moment when a unit finishes being served must be defined externally and communicated to this class by calling release(Object) method.
Author:
Andrey Malykhanov
  • Field Details

  • Constructor Details

    • Service

      public Service()
  • Method Details

    • placeRequest

      public abstract void placeRequest(T unit, Consumer<Service<T>> onServiceStarted)
      Places the request for service of the specified unit. Such placement can result in one of the two following outcomes:
      1. If the specified unit can start being served immediately, the onServiceStarted callback is called immediately and the specified unit goes into the list of served units - getServicedUnits().
      2. If the specified unit cannot start being served immediately, the unit goes into the list of waiting units - getWaitingUnits().
      Parameters:
      unit - unit that request the service
      onServiceStarted - callback called when the unit start being served. Can be called immediately if no queuing is needed
    • cancelRequest

      public abstract void cancelRequest(T unit)
      Cancels the request for service of the specified unit and removes it from the list of waiting units - getWaitingUnits().

      If the specified unit is not waiting for service, throws a RuntimeException.

      Parameters:
      unit - unit that stops waiting for the service
    • release

      public abstract void release(T unit)
      Finishes the service of the specified unit, i.e. releases the "server" used to serve this unit. Removes the specified unit from getServicedUnits() collection.

      After the unit finishes its service, it is likely that service of some other unit starts if there are units waiting for service.

      If the specified unit is not currently being served, throws a RuntimeException.

      Parameters:
      unit - unit that finishes being served
    • addServiceStartedHandler

      public void addServiceStartedHandler(BiConsumer<T,Service<T>> onServiceStarted)
      Adds a handler that is called every time the service of a unit starts.
      Parameters:
      onServiceStarted - handler that takes two arguments - the unit itself and this service
      See Also:
    • removeServiceStartedHandler

      public void removeServiceStartedHandler(BiConsumer<T,Service<T>> onServiceStarted)
      Removes a previously added handler that is called every time the service of a unit starts. Does nothing of the specified handler has not been previously added.
      Parameters:
      onServiceStarted - handler being removed
    • addWaitingUnitArrivedHandler

      public void addWaitingUnitArrivedHandler(BiConsumer<T,Service<T>> onServiceRequested)
      Adds a handler that is called every time a unit joins the queue of waiting units.
      Parameters:
      onServiceRequested - handler that takes two arguments - the unit itself and this service
      See Also:
    • removeWaitingUnitArrivedHandler

      public void removeWaitingUnitArrivedHandler(BiConsumer<T,Service<T>> onServiceRequested)
      Removes a previously added handler that is called every time a unit joins the queue of waiting units. Does nothing of the specified handler has not been previously added.
      Parameters:
      onServiceRequested - handler being removed
    • addServiceRequestRemovedCallback

      public void addServiceRequestRemovedCallback(BiConsumer<T,Service<T>> onServiceRequestRemoved)
      Adds a handler that is called every time a request for service of a unit is cancelled and it is removed from queue of waiting units without being served.
      Parameters:
      onServiceRequestRemoved - handler that takes two arguments - the unit itself and this service
      See Also:
    • removeServiceRequestRemovedCallback

      public void removeServiceRequestRemovedCallback(BiConsumer<T,Service<T>> onServiceRequestRemoved)
      Removes a previously added handler that is called every time a request for service of a unit is cancelled. Does nothing of the specified handler has not been previously added.
      Parameters:
      onServiceRequestRemoved - handler being removed
    • getServicedUnits

      public SequencedSet<T> getServicedUnits()
      Returns an unmodifiable collection of units being currently served. The order of units in this collection is reproducible but is not guaranteed.
      Returns:
      unmodifiable collection of units being currently served
    • getWaitingUnits

      public List<T> getWaitingUnits()
      Returns an unmodifiable list of units that are currently waiting for service. The order of elements corresponds to the order of their addition to the queue (FIFO).
      Returns:
      unmodifiable list of units waiting for service
    • addWaitingUnit

      protected final void addWaitingUnit(T unit)
      Adds a unit to the waiting queue
    • removeWaitingUnit

      protected final void removeWaitingUnit(T unit)
      Removes a unit from the waiting queue
    • takeNext

      protected T takeNext()
      Attempts to start service of the next unit.

      If the waiting queue is not empty, moves the next unit from this queue to the serviced units collection, then calls the corresponding handlers.

      Returns:
      the object taken from the waiting queue, or null if the queue is empty