# Observations, gaps, and reconciliation

Source: https://libtmux.org/en/scala/latest/topics/observations/

> Handle FS2 stream ownership and bounded queues without inventing delivery guarantees.

The Cats module adapts Java subscriptions to FS2. Acquire a control attachment,
then an observation, then start the producer. This order avoids asking a newly
created observer to recover an event that happened before it existed.

## One consumer owns an observation

An observation permits one active consumer. A second reader on the same
observation fails. Use an explicit broadcast when multiple parts of the
application need the same delivery, and decide how that broadcast handles its own
slow consumers.

Output values retain their pane identity. Their data is decoded terminal text,
not exact bytes or a captured screen. A text marker can span values, so keep the
necessary matching state across fragments.

## Keep gap information

| Projection | Behavior after subscription loss |
| --- | --- |
| Full delivery stream | Includes [`Delivery.Gap`](<https://libtmux.org/en/java/latest/reference/io-github-libtmux-control-delivery-delivery-gap/>) before surviving values. |
| [`Observation.value`](<https://libtmux.org/en/scala/latest/reference/io-github-libtmux-scaladsl-cats-observation-value/>) | Drops gap records. |
| [`Observation.kept`](<https://libtmux.org/en/scala/latest/reference/io-github-libtmux-scaladsl-cats-observation-kept/>) | Fails the read when loss is encountered. |

A bounded subscription can discard old values when the reader falls behind.
FS2 demand does not make tmux obey backpressure or retain a durable history.
The cumulative dropped count gives additional loss evidence; closing a
subscription discards its queued values without counting that as overflow.

Take a new snapshot before acting on event-derived topology after loss. That
recovers a current view of objects, not the missing terminal output.

## Interpret the ending correctly

An idle Cats consumer suspends its fiber on the subscription's readiness callback.
The direct-style observation instead blocks in Java for its next delivery.
Canceling a Cats reader releases its consumer slot; releasing the observation
closes the subscription.

Deliberate observation or attachment closure ends the stream. A native client
failure carries its cause. The remaining unknown-cause case is not evidence of a
specific timeout or daemon crash.

See the [streaming guide](https://libtmux.org/en/scala/latest/guides/streaming/) for loss projections and
closure behavior, and [client lifetimes](https://libtmux.org/en/scala/latest/topics/ownership/) for nested cleanup.
Use the [capture example](https://libtmux.org/en/scala/latest/examples/capture-pane-output/) when you need the
screen's current contents instead of future event delivery.
