Diagnostics
Purpose
Diagnostics exposes operational observations: session counts, queue activity, resource retirement, worker policy, asset publication and memory bookkeeping. It helps correlate a failure without changing the owning operation’s semantics.
Interface
Types below are in CE::Diagnostics unless another namespace is shown.
Types and observations
API and purpose |
|---|
|
|
|
|
|
Observation boundaries
Observation |
Purpose and details |
|---|---|
Owned completed-session counts after synchronization with run completion; live sampling rejects. Runtime statistics. |
|
Queue/group status |
Activity at the snapshot boundary; an empty queue does not prove detached work finished. Worker and dispatcher limits. |
Resource retirement statistics |
Tracked native resources and retirement/collection activity in one backend domain. Native resource statistics. |
Explicit diagnostic report |
A bounded operational summary outside sensitive locks/native callbacks; required emergency failure output has a separate path. Failure reporting; validation limits. |
Usage
Read the service that owns the observation, retain its copied values, then interpret them with the operation’s result or failure. Diagnostics does not create a global monitor that queries every subsystem for the application.
---
config:
theme: base
themeVariables:
fontFamily: system-ui, sans-serif
fontSize: 14px
flowchart:
htmlLabels: true
curve: linear
nodeSpacing: 22
rankSpacing: 38
padding: 12
---
flowchart TB
accTitle: Diagnostics · application observations
accDescr: Arrows point toward the API or type used, not call order or data flow. Methods beneath type names are selected application entry points; Implement hooks marks engine-invoked overrides. Dashed arrows mark optional choices.
k0(["Application<br/>report"]):::app
k1["<b>Runtime::<br/>GameRuntime</b><br/><br/>diagnostics(): Runtime::RuntimeStats"]:::neighbor
k2["Runtime::<br/>RuntimeStats"]:::focal
k3(["Application<br/>live observations"]):::app
k4["<b>Workers::<br/>Group</b><br/><br/>status(): Workers::GroupStatus<br/><br/>policy(): Workers::GroupPolicy"]:::neighbor
k5["Workers::<br/>GroupStatus"]:::focal
k6["<b>Runtime::<br/>PlatformDispatcher</b><br/><br/>diagnostics(): Diagnostics::DispatchStats"]:::neighbor
k7["Diagnostics::<br/>DispatchStats"]:::focal
k8["<b>Events::<br/>EventBus</b><br/><br/>diagnostics(): Events::EventStats"]:::neighbor
k9["Events::<br/>EventStats"]:::focal
k10["<b>Logging::<br/>Logger</b><br/><br/>info(fmt, args...)"]:::neighbor
k11["Workers::<br/>GroupPolicy"]:::focal
k0 --> k1
k1 --> k2
k0 --> k2
k3 --> k4
k4 --> k5
k3 --> k6
k6 --> k7
k3 --> k8
k8 --> k9
k0 -.-> k10
k4 --> k11
classDef focal fill:#e7f3ef,stroke:#387d6b,color:#153d33,stroke-width:1.2px
classDef neighbor fill:#f0f3f8,stroke:#8c9bb1,color:#35445b,stroke-width:1px
classDef app fill:#fff2df,stroke:#c09452,color:#674515,stroke-dasharray:5 3
classDef system fill:#eaf0fc,stroke:#617fab,color:#263f69,stroke-width:1.2px
linkStyle default stroke:#7e8fa7,stroke-width:1.2px
The owner dependency view shows the available snapshot families and their originating services.
Choose an observation boundary
Question |
Query/result |
When and how to interpret it |
|---|---|---|
How did this session progress? |
Synchronize with |
|
Is worker work queued/running or using fallback policy? |
|
Status observes activity/failures; policy reports effective eligibility and preferred fallback. Use each job’s future for its result. |
Is dispatched work still queued or detached? |
Platform/simulation dispatcher |
|
What happened to event delivery? |
Registration, invocation, discard and queued-failure observations; no event payload/name sampling. |
|
Did an upload publish anything before failing? |
|
Last-attempt counts/completion can describe partial publication. Keep the original upload error; no batch rollback is implied. |
Are cache entries still owned? |
Separates current entries from cumulative publications/replacements; clearing one cache does not drop every asset owner. |
|
Which CPU ranges remain managed? |
Synchronized byte-domain totals, free bytes, owners and partitions; not live-object or GPU-byte counts. |
|
Are native handles awaiting retirement? |
|
Compare live/pending/collected ownership on the selected backend; sampling performs no graphics collection. |
Follow the symptom, evidence and action table when deciding what to sample. It connects an observation to the owner whose policy or lifetime may need investigation.
Uses
Observer |
Dependency |
Relationship |
|---|---|---|
Application report |
The owner-specific snapshot APIs above |
Copies observations under each owner’s access rules; it does not acquire service ownership through the result. |
Runtime/resource/work correlation |
Joins observations from the same process-local owner. IDs are neither addresses nor persistent asset/session keys. |
|
Ordinary formatted report |
Selects a named destination after sampling, outside containing locks/native callbacks. Logging. |
|
Required native/cleanup failure report |
Preserves failure context independently of ordinary logging and leaves the owning exception/future authoritative. |
Used by
Owner |
Diagnostic identity/observation |
Useful correlation |
|---|---|---|
|
Connect a session outcome to update, polling and frame counts. |
|
Pool/group/dispatcher/bus domains and queue/delivery observations |
Distinguish admission, pending, detached/running, completion and failure. |
|
Prepared batch, |
Connect CPU preparation, provider upload and actual publication without relying on source paths. |
|
Shared byte-domain and native resource-lifetime counts |
Separate retained CPU backing from backend-native retirement. |
|
Explicit platform/native operational reports |
Inspect capabilities, resize/focus epochs or supported debug observations without assuming every native call is traced. |
Retain values, compare domains
A copied snapshot can outlive the observed service. Its values do not keep that service alive, refresh themselves or make a query safe during destruction. Retain the owner through the query and obey its thread/lifecycle boundary.
Compare counters only within the domain and scope they describe. Memory growth facades share the byte bookkeeping domain; worker group and physical pool IDs identify different owners. A zero domain means unavailable/exhausted. Counts sampled from different owners are not one atomic engine-wide snapshot. The diagnostics guide defines each family’s sampling and reporting limits.
Contracts
Counters are observations, not completion barriers, admission limits or resource budgets. Domain IDs are monotonic process-local identities, not addresses/native handles or durable keys; zero indicates exhaustion. Unavailable observations must remain explicit.
GameRuntime::diagnostics() requires caller synchronization with run start and
return; live sampling rejects. An empty dispatcher queue does not establish that
detached work completed. Asset completion counts do not establish batch rollback
or distinguish every reused key from a newly published entry without their
documented counters.
Lifecycle
An owner acquires its identity with construction and publishes observations at
documented boundaries. Take a completed runtime snapshot after run() returns
or throws, retaining the runtime through that query. Explicit reports must run
outside containing locks/native callbacks according to the subsystem contract.
Retained snapshots own their values without retaining the observed service.
Execution
Each snapshot follows the observed owner’s access rules. Reporting can allocate, format or log, so it is not suitable for arbitrary destructor/native callback contexts. Emergency reporting has a deliberately separate bounded contract and must not mask the original exception.
Integration
After synchronizing with runtime completion:
const auto stats = runtime.diagnostics();
const auto updates = stats.updates;
const auto rendered = stats.rendered;
Use these values in an application report with the run outcome. Different update/render counts are expected with independent scheduling and skipped or superseded visual snapshots. Use the symptom, evidence and action table to decide which observation to inspect before changing a scheduling or resource policy.
Limits and further reading
Counters do not measure cache speedups, native thread residency or unselected hardware behavior. Read subsystem observation limits, failure reporting, architecture acceptance limits and diagnostic declarations.