VOOZH about

URL: https://deepwiki.com/hypervel/telescope/2.1.4-context-and-batch-management

⇱ Context and Batch Management | hypervel/telescope | DeepWiki


Loading...
Last indexed: 7 February 2026 (146f77)
Menu

Context and Batch Management

Purpose and Scope

This document explains how Telescope uses the Hypervel Context system to manage recording state, batch identifiers, and entry queues in a coroutine-safe manner. The Context system provides isolated storage for each coroutine context, ensuring that concurrent requests do not interfere with each other's Telescope data.

For information about how entries are persisted to storage, see Storage Lifecycle Management. For details on the entry data structures themselves, see IncomingEntry.

Sources: src/Telescope.php1-750

Context System Overview

Telescope leverages the Hypervel\Context\Context class to store per-coroutine state. This design is essential in Hyperf's coroutine-based architecture, where multiple requests may be processed concurrently within the same process. Each coroutine maintains its own isolated context, preventing data leakage between concurrent operations.

The Context system provides three key operations used throughout Telescope:

MethodPurposeUsage in Telescope
Context::set($key, $value)Set a value in the current coroutine contextRecording state flags and queues
Context::get($key, $default)Retrieve a value from contextCheck recording state, fetch queues
Context::override($key, $callback)Atomically update a context valueAppend entries to queues
Context::getOrSet($key, $callback)Get or initialize a value lazilyGenerate batch IDs

Sources: src/Telescope.php13 src/Telescope.php218-233 src/Telescope.php241 src/Telescope.php308-310

Context Keys

Telescope defines six context keys as class constants, each serving a specific purpose in managing the recording lifecycle:


Context Key Definitions

ConstantValueTypePurpose
SHOULD_RECORDtelescope.should_recordboolMaster switch indicating whether Telescope should record entries
IS_RECORDINGtelescope.is_recordingboolRecursion guard preventing entries from being recorded during recording
HAS_STOREDtelescope.has_storedboolFlag ensuring storage is triggered only once per context
BATCH_IDtelescope.batch_idstringUUID grouping related entries (e.g., all queries in a request)
ENTRIES_QUEUEtelescope.entries_queuearrayBuffer of IncomingEntry objects awaiting storage
UPDATES_QUEUEtelescope.updates_queuearrayBuffer of EntryUpdate objects for modifying existing entries

Sources: src/Telescope.php36-46

Recording State Management

State Transitions


Sources: src/Telescope.php216-270

SHOULD_RECORD Flag

The SHOULD_RECORD flag is the primary control for Telescope's recording behavior. When true, watchers will record entries; when false, all recording is disabled.

Initialization:

  • Set to true by startRecording() if recording is not paused in cache
  • Set to false by stopRecording()
  • Checked by isRecording() before any recording operation

Sources: src/Telescope.php216-234 src/Telescope.php239-242 src/Telescope.php263-270

IS_RECORDING Flag (Recursion Prevention)

The IS_RECORDING flag prevents infinite recursion when Telescope's own operations (e.g., checking authentication, logging) would trigger watchers.

Mechanism:

  1. Before recording an entry, record() checks if IS_RECORDING is true
  2. If true, the entry is silently discarded (recursion detected)
  3. If false, sets IS_RECORDING = true, processes entry, then resets to false

Sources: src/Telescope.php281-319

HAS_STORED Flag (Storage Trigger)

The HAS_STORED flag ensures that storage is scheduled exactly once per context, even when multiple entries are recorded.

Behavior:

  • First time record() is called, checks HAS_STORED
  • If false, schedules deferred storage via defer() and sets HAS_STORED = true
  • Subsequent record() calls in the same context skip the defer scheduling

Sources: src/Telescope.php285-290

Batch Management

Batch ID Generation

The BATCH_ID is a UUID that groups all entries recorded within a single context. For example, an HTTP request's batch includes:

  • The request entry itself
  • All database queries executed
  • All cache operations performed
  • All logs generated
  • All events fired

Generation:


The method uses Context::getOrSet() for atomic get-or-initialize behavior:


Sources: src/Telescope.php665-668

Batch Assignment to Entries

When entries are collected for storage, each entry in the queue is assigned the batch ID:


Sources: src/Telescope.php642-652

Cross-Batch Relationships

Some operations span multiple batches. For example, a queue job may be dispatched in one request (Batch A) and executed later (Batch B). Telescope handles this through:

  1. Family Hash: Groups related entries across batches (not managed by Context)
  2. Updated Batch ID: Entries can be updated with a new batch ID when modified

Sources: src/Telescope.php657-663

Queue Management

Entry Queue Structure

The ENTRIES_QUEUE is an array of IncomingEntry objects accumulated during the current context's execution.


Adding to Queue:

The record() method uses Context::override() to atomically append entries:


This pattern ensures thread-safe appending even if multiple operations attempt to add entries concurrently within the same coroutine.

Sources: src/Telescope.php308-310 src/Telescope.php324-327

Update Queue Structure

The UPDATES_QUEUE holds EntryUpdate objects that modify previously stored entries. These are used when an entry's state changes after initial storage (e.g., a job's status updating from "pending" to "completed").


Sources: src/Telescope.php340-349 src/Telescope.php332-335 src/Telescope.php657-663

Queue Flushing

After entries are stored, both queues are flushed to prevent memory leaks and duplicate storage:

MethodPurposeWhen Called
flushEntries()Clears ENTRIES_QUEUEAfter executeStore() completes
flushUpdates()Clears UPDATES_QUEUEAfter executeStore() completes

Sources: src/Telescope.php498-513 src/Telescope.php635-636

Coroutine Propagation

In Hyperf's coroutine model, child coroutines may be spawned from parent coroutines (e.g., when dispatching async operations). Telescope ensures context is properly inherited using Hyperf's Coroutine::afterCreated() hook.


Propagated Context Keys

The TelescopeServiceProvider configures propagation for three keys:


Rationale:

  • SHOULD_RECORD: Child inherits parent's recording state to maintain consistent behavior
  • IS_RECORDING: Child starts with parent's recursion state (typically false)
  • BATCH_ID: Child shares parent's batch ID so all related operations are grouped together

Not Propagated:

  • ENTRIES_QUEUE and UPDATES_QUEUE are not copied, allowing parent and child to maintain separate entry buffers
  • HAS_STORED is not copied, ensuring each coroutine manages its own storage lifecycle

Sources: src/TelescopeServiceProvider.php38-47

Entry Recording Lifecycle

The following diagram illustrates the complete flow from watcher detection to batch storage:


Sources: src/Telescope.php275-319 src/Telescope.php579-637 src/Watchers/CacheWatcher.php59-117

Context Isolation Example

To illustrate how context isolation works in practice, consider two concurrent HTTP requests:


Each request maintains completely isolated:

  • Batch IDs (different UUIDs)
  • Entry queues (different entries)
  • Recording states (independent flags)

This isolation is automatic through Hypervel's Context system and requires no manual synchronization.

Sources: src/Telescope.php36-46 src/TelescopeServiceProvider.php38-47

Performance Considerations

Memory Management

The context-based queue system accumulates entries in memory until storage is triggered. For high-throughput applications:

  • Entry Queue Growth: Limited by request lifetime; cleared after storage
  • Batch ID Reuse: Single UUID per context minimizes memory overhead
  • Queue Flushing: Automatic cleanup via flushEntries() and flushUpdates()

Coroutine Overhead

The afterCreated() hook runs for every spawned coroutine, copying three context values. This overhead is minimal but occurs frequently in applications with many async operations.

Sources: src/Telescope.php498-513 src/Telescope.php635-636 src/TelescopeServiceProvider.php38-47

Summary

Telescope's context and batch management system provides:

  1. Coroutine-Safe State: Isolated recording state per coroutine via Context
  2. Batch Grouping: UUID-based grouping of related entries
  3. Recursion Prevention: IS_RECORDING flag blocks infinite loops
  4. Memory Efficiency: Queues flushed after storage, deferred storage via defer()
  5. Parent-Child Propagation: Automatic context inheritance for child coroutines

This design enables Telescope to function reliably in Hyperf's concurrent environment without manual locking or synchronization.

Sources: src/Telescope.php1-750 src/TelescopeServiceProvider.php23-48