Stream network lifetime
After you create a stream or stream listener, it exists until one of the following happens:
You explicitly terminate it.
The monitor that contains the stream or stream listener terminates.
You terminate another stream or stream listener in the same stream network and that causes the stream or stream listener to terminate.
A stream or stream listener is explicitly terminated by calling the quit() method on a variable that refers to it. Hence, to explicitly terminate a stream or stream listener, you must retain a reference it. You can also terminate a stream or stream listener by terminating a related stream or stream listener in the same stream network (as detailed below).
You can create a stream or stream listener that is not referenced by any variable and cannot be terminated by quitting any other streams or stream listeners in the stream network. If this is unintentional then we refer to it as a stream or stream listener leak. This situation is similar to an event listener leak (see
Avoiding listeners and monitor instances that never terminate. Here is an example:
action createStreamListener returns listener {
stream <A> sA := all A();
return from a in all A() select a.x: x { print x.toString(); }
// error: meant to use sA in the query above
}
Although executing the code returns a listener variable that refers to the created stream listener, it inadvertently creates an unreferenced stream (the local variable sA did refer to this stream but is no longer in scope).
Calling quit() on a stream or stream listener in a stream network typically has side effects. A side effect can be one of the following:
Termination of additional streams, stream queries, stream listeners, or stream event expressions.
Disconnection between the terminated element and another element.
When determining which queries to terminate the correlator uses the following rule: when, due to another stream or query terminating, a query can no longer generate any output, it is also terminated. An example of how this works is probably beneficial. The following diagram shows a stream network with two stream source templates generating input events for five queries, eventually connected to two stream listeners. There are four stream variables pointing to the streams in the network.
Suppose you call quit() on either r6 or r7 (the stream variables on the right). The correlator terminates the whole of the branch from Query D down. This is because, whichever stream you quit, nothing can be generated by anything connected to those streams. Stream 4, however, is also feeding Query C, which can still generate output. Therefore, the rest of the network, including Query B and both stream event expressions, remains active.
If you subsequently call quit() on r5 this will terminate the stream listener and Query C, which will then terminate stream 3 and stream 4, since they are not connected to any other queries, and also stream 1, stream 2 and both stream source templates.
The stream variables after their streams are terminated will be dummy references. Subsequent attempts to create a query using those streams are ignored (the result is an inert stream).