TeeTime's ability to execute multiple stages simultaneously is its biggest feature and is - by a high chance - the reason you are using it.
To uncover the potential of a parallel pipe and filter architecture, let's stray from this domain a little bit.
The idea of separating individual steps of a certain process to increase efficiency and throughput is followed by many domains.
For instance, Henry Ford introduced the assembly line into the car manufacturing industry in 1913.1
The whole assembly process of the Tin Lizzy was separated into 84 discrete steps (filter), which were executed simultaneously.
Every car passed one step after another in a certain sequence (pipe connections).
Each step was performed by specialized worker which did not need to wait for other processes to finish.
Therefore, the capacities were fully utilized and idle times were reduced to a minimum.
With this approach, Henry Ford was able to increase the throughput significantly and satisfy the demand on cars.
So, why not use this approach for high-throughput software scenarios?
Let's suppose you want to implement a program which creates "Tin Lizzy instances".
After the first tutorial you already know how to separate the program into discrete steps.
Now, your main focus is on high throughput.
However, your configurations could only run in one thread until now.
As a result, only one stage is executed at any given time, while the remaining ones are idle.
Processing power is wasted.
To increase throughput, you can separate the process into two or more parts which run parallel.
For now, there is no "correct way" on where to divide the process. You need to analyze your program and find the best solution yourself. (In future releases, TeeTime will provide functionality to simplify this.)
After discovering a suitable intersection point, you need to call declareActive() on the stage which should run in a separate thread.
This needs to be done before the execution of the configuration.
Consider following configuration as an example:
By default the first stage - stage A - is declared active.
Therefore it runs also all subsequent stages in its thread.
Now suppose stage A and B are able to run parallel but stage C depends somehow on stage B.
In such case, it is useful to declare stage B active so it can run in its own thread.
We call B.declareActive().
As a result, stage A and B run in separate threads.
Furthermore, as stage C remains passive, it runs in the same thread as stage B, as it is stage B's successor.
TeeTime will automatically choose the right pipes for you, so you do not need to worry about the synchronization of the communication between the stages.