A Simple Discrete-Event Simulation: Part 47

Today I spent quite a lot of time really trying to nail down every facet of the logic to be used to route entities between components. I drew diagrams in Visio and I went through several modifications of a logic table in Excel until things started to become clear to me. The table is shown directly below (scroll sideways to see the whole thing).

 
The Arrivals component is not discussed in the table because it logically transfers entities only to Entry components which must be able to receive them at all times. Entry components forward entities immediately upon receipt to other components that are likewise required to receive them. Exit components are required to immediately receive all entities. Entry components, trivially, should not be connected directly to Exit components. Beyond that things get interesting.

I found that the basic connection logic repeats consistently across most connections between most combinations of components and it works like this. If the receiving components are non-exclusive they can immediately receive any entities forwarded to them. It may be that very few instantiations of Process components would not be exclusive (i.e., limited in the number of entities it can hold at one time) but it is possible to imagine such things. Queues are exclusive when a hard capacity is defined for them (this can be done in many ways but for now we’ve only implemented a simple one that goes by entity count). When downstream components are defined as being exclusive they cannot receive entities until they clear and give permission. If sending entities have to wait for permission to forward entities to exclusive downstream components they “lose” their future events queue item and go into an implicit wait state. It is therefore up to the exclusive downstream entity to send a request back upstream to the sending entity to get things moving again. The upstream entity sends the next entity if one is ready.

If a sending component is connected to a single downstream component (with or without a Path component), the handshaking procedure is straightforward. If a sending component is linked to multiple downstream components of the same type it uses distribution logic to try to forward entities downstream on a rotating basis (subject to those components being closed). When downstream components clear they turn around and send a request back upstream to pull the next entity. If a sending component is linked to multiple downstream components of different types (we’ll discuss this going forward–in this case the downstream components might all be of the same simulation type, e.g., Process, but they may all be different logical types which represent different real world activities, which is the point of this exercise), then the entities are forwarded downstream to destinations based on a routing table. This works the same way as the connection between the Arrivals component and the Entry components where a random number determines the destination. If the upstream component cannot send an entity downstream because the receiving entity is exclusive and closed it waits until the downstream component clears and sends the necessary request.

I had a lot of visions in my head of possible complication from thinking about all of this but filling out the logic table in detail helped me organize and clarify all of them. The first insight I had was that distribution logic is pretty simple. The upstream component can either forward and entity to a downstream component or it can’t. If it can’t it wait for the next downstream component to send a request back upstream. Things get trickier when using routing logic in that the upstream entity might have to wait to send an entity downstream to a component that is exclusive and closed. The question then becomes whether the next entity in the upstream component, that wants to be forwarded to a different downstream component, has to wait for the entity ahead of it to get out of the way. There are some cases where entities do have to wait for others in front of them to clear and other cases where they do not. I refer to this as downstream exclusivity, and I’ll be creating a new component property to handle this setting. Components like Bags (e.g., parking lots) would usually be non-exclusive while single-path/FIFO queues and processes would usually be exclusive. A more general type of queue might be non-exclusive in this way.

The logic for Path components is also a bit confusing. When talking about Path components connecting to other types of components we see that for the most part Path components take on the exclusivity characteristic of the downstream component. When talking about other types of components connecting to Paths we see that the idea of multiple components connecting to a single Path doesn’t make much sense. For the time being, finally, we see that Paths connecting to other Paths only can be done serially without branching.

So far I’ve discussed what happens when a single component connects to one or more components in the downstream direction. We also need to analyze what happens when multiple upstream components connect to a single downstream component. If the downstream component is not exclusive then no big deal–the downstream component (think of an Exit component or a non-exclusive Queue component) simply receives every entity sent to it. If the downstream component is exclusive, however, then the downstream component may have to maintain a queue to keep track of the order in which it should send requests back to the upstream components. Alternatively, it could simply rotate through the upstream components in a mirror of the distribution logic used to forward entities downstream. But wait–it gets even crazier! What if multiple upstream components are connected to multiple downstream components in a many-to-many fashion? In that case it seems like all of the downstream components would have rotate their pull requests through the upstream components. This logic will get tested and implemented after everything else discussed here has been addressed. I’m actually not sure how often it would really come up, but we definitely have to keep this idea in mind.

This idea is captured in the logic table as the lines for downstream components being connected to single upstream components (1 src) or being connected to multiple upstream sources (>1 src). A lot of the logic doesn’t change between having one upstream source or many, but some does.

Let me formally add to the existing To Do list:

  • New property for forward exclusivity as opposed to receiving exclusivity.
  • Formalize and implement method of receiving from multiple upstream components in turn. Implementing and observing this may illuminate the behaviors that will need to be implemented for the general path solution described in one or more previous posts.
This entry was posted in Simulation and tagged . Bookmark the permalink.

Leave a Reply