Connections

A connection is more than an arrow on the canvas — it is a contract between an active and a passive component, and it is where queueing behaviour actually comes from.

Push and pull#

Every connection has an active side and a passive side. A Generator pushes: it decides when an entity exists and hands it downstream. A Server pulls: it asks its source for work, and once the work is done it pushes the finished entity onward. A Queue is passive — it never acts on its own, it only answers the components attached to it. A Delay is both: it is fed like a queue and pushes onward like a generator.

That is why Generator → Queue → Server is the shape everything is built from: an active component on each end, with the passive buffer in the middle absorbing the difference in pace. Connecting two active components directly leaves nowhere for the mismatch to go.

Full queues and waiting#

The two sides of a connection are not equally patient. A pull from an empty queue waits for an entity, for as long as it takes — an idle server loses nothing by waiting. As soon as an entity arrives it is handed straight to the waiting server, without ever being stored.

A push into a full queue does not wait. The queue refuses the entity on the spot, the component that pushed it counts it as dropped, and it leaves the model. This is the loss that shows up on the entity rate charts and in the dropped figures, and while the model runs each refusal is drawn as a red dot on the connection it was refused on.

A server whose finished entity is refused drops it and goes straight back to pulling new work. Congestion therefore does not travel backwards through a model: a full queue turns work away at its own door, and the stages in front of it carry on at their own pace.

Components still show a Wait Timeout setting, greyed out. It does nothing today. Patience will return as a setting of the component doing the pushing, so that a producer can wait for space and give up after a while.

Multiple connections#

A component may have more than one connection on either side. Outgoing connections are served round-robin, so entities are spread evenly across the downstream branches rather than favouring one; incoming connections are polled round-robin in the same way, so a server drawing from two queues alternates between them.

Round-robin does not look ahead. An entity refused by a full branch is dropped, not offered to the next branch, and a server whose turn has come on an empty queue waits there even if the other queue has work.

Round-robin distributes turns, not load. Two branches with different service rates each receive half the entities, and the slower branch is the one that backs up — which is often exactly the effect you want to demonstrate.

When a Server or Delay has no outgoing connection at all, entities leaving it are counted as completed and exit the model. That makes the last server in a chain a natural exit point — there is no separate sink component to place. Cycle time is measured at these exits.

Wiring rules#

A model has to be wired up before it can run. The simulator checks these rules when you press play, highlights any component that breaks one, and explains what is missing:

  • A Generator must have an outgoing connection — it has nowhere to put entities otherwise.
  • A Queue must have an incoming connection — nothing would ever fill it.
  • A Server must have an incoming connection — it has nothing to pull from otherwise.
  • A Delay must have an incoming connection — nothing would ever pass through it.
  • Every connection must join an active side to a passive one. Two components that both start transfers — a generator, server or delay feeding straight into a server — need a queue between them. Two that both wait to be asked — a queue feeding a queue or a delay — would never move anything.

The simulator enforces the last rule as you draw: while you drag a connection, only the inputs it can legally join are offered.

Outgoing connections are optional. On a server or a delay, an unconnected output is a legitimate exit from the model — entities that leave it count as completed. A queue with no outgoing connection is accepted too, but nothing will ever drain it, so it fills to capacity and refuses everything after that.