π°οΈ Tracking Stream Execution with Tracker and trackable β
β οΈ Warning: Subscribers will not receive notifications for values that are filtered or suppressed by pipeline operators, so tracker status method will be not called as expected, and will hang indefinitely. We are actively working to support these cases.
Reactive systems thrive on observability. But when streams become deeply nested or asynchronous, tracking their execution status can quickly spiral into complexity. Thatβs where Tracker and trackable come in β two utilities designed to bring clarity, control, and lifecycle awareness to your reactive workflows.
π΅οΈββοΈ What Is a Tracker? β
A Tracker is a lightweight utility for monitoring the execution status of Streamix streams. It maintains a registry of active streams, tracks their lifecycle, and exposes tools for synchronization, cleanup, and status inspection.
π Core Capabilities β
- Track Execution: Registers streams as they begin execution.
- Set Status: Marks streams as executed once all selectors have run and data updates for a dispatched action are complete.
- Complete & Remove: Cleans up streams from the registry when they finish or are unsubscribed.
- Reset: Clears the execution status of all entries without removing them, preparing for the next action.
- Synchronize: Awaits the completion of all tracked streams via
allExecuted()
, guaranteeing that all state propagation and derived data updates are finished.
π§© Why Tracking Matters β
In reactive applications, streams often represent side effects: API calls, animations, user interactions, or state transitions. Without tracking, itβs difficult to answer questions like:
- βHas everything finished executing?β
- βAre there any lingering subscriptions?β
- βCan I safely dispatch the next action?β
By integrating a Tracker, you gain:
- β Execution visibility
- β Lifecycle synchronization
- β Automatic cleanup
- β Safer state propagation
π§ͺ Making Streams Trackable β
The trackable()
function wraps a Streamix stream and automatically registers it with a Tracker. It overrides the .subscribe()
method to inject lifecycle hooks:
const trackedStream = trackable(originalStream, tracker);
π οΈ What It Does β
- On subscription: Registers the stream via
tracker.track()
. - On emission: Marks the stream as executed via
tracker.setStatus()
. - On error or completion: Cleans up via
tracker.complete()
.
This ensures that every streamβs lifecycle is fully observable β without manual intervention.
π Tracker-Aware State Propagation β
Within the store state updates are synchronized with the Tracker's status. This ensures that all reactive side effects, such as selectors and data updates, are executed before the store's state is considered stable and ready for the next action. This prevents race conditions and ensures a predictable data flow.
The store implements this by optionally awaiting the Tracker after an action has been dispatched:
π A Meme-Worthy Example β
Letβs say youβre building an app where users fetch their profile data, and you need to know when itβs done before moving on. Without Tracker, itβs like sending a kid to the store for snacks and hoping they donβt get distracted by a puppy. With Tracker, itβs more like:
const tracker = store.tracker; // The hall monitor with a walkie-talkie
const userStream = trackable(userModule.data$.getUser(), tracker); // Slap a GPS on that stream!
userStream.subscribe({
next: (user) => console.log(`User ${user} arrived with snacks! π`),
error: (err) => console.error(`User got lost in the TikTok void: ${err}`),
complete: () => console.log('User went home, partyβs over π')
});
// Wait for everyone to finish their snacks
await tracker.allExecuted(); // "No one leaves until the chips are gone!"
tracker.reset(); // "Alright, clean up for the next snack run!"
This pattern is especially useful in workflows that depend on stream completion before proceeding β such as form submissions, chained actions, or UI transitions.
π€ Why This Duo Saves Your Sanity β
- No Ghost Streams: Tracker ensures no streams are haunting your app after theyβre done.
- No Race Condition Raves: Synchronization means your actions donβt step on each otherβs toes.
- Debugging Like a Boss: Know exactly which stream is slacking or causing trouble.
- Scales Like a Pro: Handles everything from a single API call to a full-on stream mosh pit.
π§ Key Benefits β
Feature | Description |
---|---|
β Automatic Lifecycle | No need to manually track or clean up streams |
β Status Visibility | Inspect whether a stream is active or completed |
β Synchronization | Await all streams before dispatching or updating state |
β Robust Error Handling | Ensures tracker cleanup even if receiver logic fails |
β Scalable Integration | Works seamlessly with Streamix, ActionStack, and custom reactive flows |
π Beyond Tracking: Measuring with Perfmon β
While Tracker and trackable give you visibility into when streams start, finish, or get cleaned up, sometimes you also need to know how much impact each action has on performance.
Thatβs where perfmon from @actioncrew/actionstack/tools comes in.
π§ What is Perfmon? β
perfmon is a lightweight performance monitor built into Actionstack. It measures execution time, frequency, and impact of every dispatched action, so you can correlate which actions are slow with how streams are behaving.
π How it Works with Tracker β
Tracker β Observes current action lifecycle (whoβs completed, whoβs done).
Perfmon β Observes the cost of actions (how long updates and side-effects take).
Together, they give you a full observability story:
Perfmon tells you "Action X took 75ms and triggered 12 selectors".
Tracker tells you "These 12 streams already have emitted and emission payload has been accepted by related subscribers".
π§΅ Final Thoughts β
The combination of Tracker and trackable brings structure and observability to reactive systems. Whether you're managing UI state, coordinating async workflows, or building complex stream pipelines, these utilities help ensure that every stream is accounted for β and that your application remains predictable, performant, and easy to debug.
Track every stream, chase every dreamβyour appβs ready to shine! ππ