@@ -245,47 +245,59 @@ sender:
245245Conduit filters
246246^^^^^^^^^^^^^^^
247247
248- A conduit filter lets a conduit skip past an in - between timeline(s): a component can send
249- directly to (or receive directly from ) another one further down or up the nesting,
250- without the message being relayed through whatever sits between them. Because the
251- deeper side of such a conduit still gets called multiple times for every step the
252- shallower side takes, skipping down needs a filter that produces enough messages to
253- match (`` repeat`` / `` pad`` ), and skipping back up needs one that picks a single message
254- out of the many produced (`` last`` ). A conduit between directly connected timelines (a
255- component and its own caller) doesn' t skip anything, so it can' t take a filter at all .
256-
257- - `` repeat`` and `` pad`` cross from an outer timeline into a nested one: a single
258- message sent on the outer timeline (e.g. an initial state) is repeated, or followed
259- by empty messages, to match every receive on the nested timeline.
260- - `` last`` crosses from a nested timeline back out to its parent: of the many messages
261- sent on the nested timeline, only the last one (e.g. a final result) is passed on.
262-
263- Filters are written in front of the receiver and may be combined:
264-
265- .. code- block:: yaml
266- :caption: Specifying conduit filters in yMMSL
267-
268- conduits:
269- macro.init_out: repeat micro.init_in
270- micro.state_out: last macro.final_in
271-
272- Extending the macro- meso- micro example from :ref:`Timelines` : `` macro`` lives on the
273- root timeline `` :`` , `` meso`` on `` :macro`` , and `` micro`` on `` :macro:meso`` . The
274- conduits that call `` meso`` and that call `` micro`` from `` meso`` are each a direct
275- connection, so neither needs a filter . A conduit that goes directly from `` macro`` to
276- `` micro`` , bypassing `` meso`` , does:
248+ A conduit connects two components that call each other directly, for example `` macro``
249+ and `` meso`` , or `` meso`` and `` micro`` . `` macro`` and `` micro`` are not directly
250+ connected in this sense: `` meso`` sits between them. Connecting `` macro`` and `` micro``
251+ directly, bypassing `` meso`` , means their pace no longer matches: `` micro`` is still
252+ called many times for every step `` macro`` takes, and still produces a message on
253+ every one of those calls, even though there is no longer a `` meso`` in between to
254+ absorb the difference. A conduit filter reconciles that mismatch.
255+
256+ Extending the macro- meso- micro example from :ref:`Timelines` with a conduit that
257+ bypasses `` meso`` to connect `` macro`` and `` micro`` directly shows both filters in
258+ use:
277259
278260.. literalinclude:: conduit_filters_bypass.ymmsl
279261 :caption: `` docs/ conduit_filters_bypass.ymmsl``
280262 :language: yaml
281263
282264.. figure:: conduit_filters_bypass.svg
265+ :align: center
283266 :alt: macro and micro have an extra pair of ports directly connecting them,
284267 bypassing meso, labeled " repeat" and " last" .
285268
286269 The same model, visualized with `ymmsl2svg
287270 < https:// github.com/ multiscale/ ymmsl2svg> `_.
288271
272+ `` macro`` produces the `` bypass_out`` message once, but `` micro`` is called many times
273+ for every step of `` macro`` and needs the message on each of those calls. The conduit
274+ from `` macro.bypass_out`` to `` micro.bypass_in`` uses a `` repeat`` filter for this: the
275+ single message `` macro`` sends is resent to `` micro`` every time it runs, without
276+ `` meso`` having to relay it.
277+
278+ The reverse happens on the way back: `` micro`` produces a `` bypass_out`` message on
279+ every one of its many runs, but `` macro`` still expects only one message per call. The
280+ conduit from `` micro.bypass_out`` to `` macro.bypass_in`` uses a `` last`` filter to
281+ reduce those many messages down to the single most recently produced one.
282+
283+ - `` repeat`` and `` pad`` go from the shallower side to the deeper one: a single message
284+ is repeated, or followed by empty messages, to match every time the deeper side
285+ receives.
286+ - `` last`` goes from the deeper side back to the shallower one: of the many messages
287+ produced, only the last one is passed on.
288+
289+ A conduit between two components that call each other directly doesn' t skip anything,
290+ so it can' t take a filter at all.
291+
292+ Filters are written in front of the receiver and may be combined:
293+
294+ .. code- block:: yaml
295+ :caption: Specifying conduit filters in yMMSL
296+
297+ conduits:
298+ macro.init_out: repeat micro.init_in
299+ micro.state_out: last macro.final_in
300+
289301
290302Nesting models
291303``````````````
0 commit comments