Problem
Several recent stability bugs shared the same root cause: the collector accepted work implicitly, but later lifecycle code did not always know whether that work was actually accepted, rejected, overflow-dropped, or stranded in a stopped queue.
Examples:
AddValue() has no return value, so tests can only infer whether a value was accepted by observing eventual sends.
SendFileAsync() returns bool, but internal file queue enqueue/drop/flush behavior is still not expressed as a typed result.
DataProcessor.AddData/AddPriorityData/AddCommand/AddFile currently gate on lifecycle and then enqueue, but a stopped/stopping queue may still accept writes internally unless every call path is perfectly ordered.
- Overflow handling is returned as an integer count, not as a semantic enqueue outcome.
This makes shutdown races harder to reason about and harder to port to C++ consistently.
Goal
Introduce an internal typed enqueue result so collector internals can distinguish accepted work from rejected/stopped/overflow-dropped work.
This does not require changing the public sensor API in the first step.
Proposed direction
Add an internal result type, for example:
internal enum EnqueueStatus
{
Accepted,
RejectedCollectorNotAcceptingData,
RejectedQueueStopped,
DroppedByOverflow
}
internal readonly struct EnqueueResult
{
public EnqueueStatus Status { get; }
public int DroppedCount { get; }
}
Then update internal queue/data processor paths so they return and log/diagnose explicit outcomes:
QueueProcessorBase.Enqueue(...) should not silently accept into a stopped terminal queue.
DataProcessor.AddData/AddPriorityData/AddCommand/AddFile should handle result status consistently.
- Queue overflow diagnostics should be driven by
DroppedCount, not by an ambiguous integer.
Public APIs can continue returning their existing values initially. For example, AddValue() can remain void, while internal tests assert the queue state/result through collector internals.
Acceptance criteria
- Queue enqueue methods return an internal semantic result instead of only an overflow integer.
- Enqueue into a stopped terminal queue is rejected explicitly, not silently stored.
- Existing public API signatures remain unchanged unless a separate API decision is made.
- Existing queue overflow behavior remains covered and unchanged from the user's point of view.
- Stability tests cover at least:
- no accepted value can remain stranded in a stopped queue;
- overflow still reports dropped values;
- terminal dispose does not hang while rejecting or clearing work.
- Full managed collector tests pass.
- Conformance and native CTest pass.
Notes
This is a stepping stone for the C++ port: native code should model the same internal statuses even if its public API remains simple.
Problem
Several recent stability bugs shared the same root cause: the collector accepted work implicitly, but later lifecycle code did not always know whether that work was actually accepted, rejected, overflow-dropped, or stranded in a stopped queue.
Examples:
AddValue()has no return value, so tests can only infer whether a value was accepted by observing eventual sends.SendFileAsync()returnsbool, but internal file queue enqueue/drop/flush behavior is still not expressed as a typed result.DataProcessor.AddData/AddPriorityData/AddCommand/AddFilecurrently gate on lifecycle and then enqueue, but a stopped/stopping queue may still accept writes internally unless every call path is perfectly ordered.This makes shutdown races harder to reason about and harder to port to C++ consistently.
Goal
Introduce an internal typed enqueue result so collector internals can distinguish accepted work from rejected/stopped/overflow-dropped work.
This does not require changing the public sensor API in the first step.
Proposed direction
Add an internal result type, for example:
Then update internal queue/data processor paths so they return and log/diagnose explicit outcomes:
QueueProcessorBase.Enqueue(...)should not silently accept into a stopped terminal queue.DataProcessor.AddData/AddPriorityData/AddCommand/AddFileshould handle result status consistently.DroppedCount, not by an ambiguous integer.Public APIs can continue returning their existing values initially. For example,
AddValue()can remainvoid, while internal tests assert the queue state/result through collector internals.Acceptance criteria
Notes
This is a stepping stone for the C++ port: native code should model the same internal statuses even if its public API remains simple.