Skip to content

TaskTonic: Dos and Don'ts

When building applications with TaskTonic, adhering to these core principles will ensure your code remains responsive, thread-safe, and easy to test.

Execution & Flow

  • DO think in atomic units of work called "Sparkles". Code within a Sparkle executes sequentially and cannot be interrupted by other Sparkles in the same Catalyst.

  • DON'T use time.sleep(). Ever. It will freeze the Catalyst thread, blocking the entire queue and making your application unresponsive.

  • DON'T use heavy, blocking while True loops inside a Sparkle.

  • DO use built-in timers (ttTimerSingleShot, ttTimerRepeat) for delays and periodic tasks. They are non-blocking and automatically schedule Sparkles.

  • DO use the Chunked Iterator pattern (processing small batches and explicitly re-queuing the next batch) when handling massive datasets to keep the queue flowing.

  • DON'T manually manage threads (threading.Thread) or thread locks (Lock()) for application logic. TaskTonic's single-threaded Catalyst execution provides inherent thread safety per component.

  • DO spin up a separate, dedicated worker Catalyst (ttCatalyst) if you absolutely must execute a heavy, CPU-bound calculation (like a massive NumPy matrix operation) to keep the Main Catalyst free for UI and I/O.

## State Management

  • DO use the built-in State Machine (self.to_state()) to manage complex, multi-step asynchronous flows (like network handshakes).

  • DON'T litter your code with boolean flags (e.g., is_connected, is_waiting). Let the state machine handle the logical mode of your Tonic.

  • DO rely on "Late State Binding". Remember that the state is checked when a Sparkle is executed from the queue, not when it is queued. This naturally protects against stale asynchronous calls.

  • DON'T force a state machine if your Tonic is a simple, stateless data pipeline. It's perfectly fine to remain in the default stateless mode (state = -1).

## Data Store (ttStore)

  • DO use .at('path') to create live Item cursors if you access the same path repeatedly (e.g., in a fast timer loop) instead of parsing the path string every time.

  • DO use "Smart Lists" (appending with # syntax) when managing lists of entities in the store to ensure Pub/Sub subscriptions trigger correctly.

  • DO use the extract and trigger_now parameters when subscribing to ttStore paths to receive safe, flat dictionary snapshots immediately.

  • DON'T update large collections item-by-item. Use .set_each() or the group() context manager to batch updates and prevent redundant Pub/Sub notification storms.

  • DO use the source() context manager and ignore_source in subscriptions when building bidirectional syncing to prevent infinite feedback loops.

  • DON'T unsubscribe by raw path strings. Always unsubscribe by owner (e.g., self.ledger.formula.unsubscribe(self)) in your ttse__on_finished hook to ensure clean garbage collection.

## Services & Architecture

  • DO use _tt_is_service to define Singleton services (like Database Managers or shared API clients).

  • DON'T modify Service attributes directly inside the _tt_init_service_base hook if the Service runs on a different Catalyst thread. Use that hook solely to place an asynchronous Command Sparkle (ttsc__) onto the Service's queue.

  • DO break large, monolithic logic into a hierarchy of Parent and Child Tonics (Base and Infusions). The Ledger will cleanly handle the teardown cascade automatically.

  • DO use ttsc__finish() as the official stop command. Never attempt to manually destroy a Tonic or bypass the lifecycle hooks.

## Testing & Distiller

  • DO use the ttDistiller for unit and integration tests. It turns asynchronous flows into predictable, synchronous, inspectable steps.

  • DON'T rely solely on self.log() for testing. Console output cannot fail a CI/CD pipeline.

  • DO use distiller.sparkle(contract={...}) to write declarative integration tests that pause execution the moment complex, multi-tonic conditions are met.

  • DO use the Distiller's Markdown Generator (md_create, md_add_trace_table, etc.) to produce living documentation of your test runs.

TaskTonic_Dos_and_Donts.md

TaskTonic_Dos_and_Donts.md weergeven.