Skip to content

findings core

Brian Lehnen edited this page Apr 8, 2026 · 2 revisions

Core Pattern Pages Audit — Findings

Audit date: 2026-03-29 Auditor: Implementation Engineer (Task 2, Phase 1) Source branch: master (F:\Git\DotNetWorkQueue) Wiki pages audited: 12


Summary

The most pervasive issue across all consumer and producer pages is a broken logging API call. Every page that shows a handler with logging uses notifications.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => ...) — a custom lambda-based overload that no longer exists. The Log property on IWorkerNotification is now Microsoft.Extensions.Logging.ILogger, which uses a completely different calling convention. Beyond logging, the pages are structurally accurate — interfaces, factory methods, and configuration shape all match the source.


Findings

[Consumer.md] Line ~45

Wiki says:

notifications.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => "Cancel has been requested - aborting");

Source says: IWorkerNotification.Log is typed as Microsoft.Extensions.Logging.ILogger (confirmed in IWorkerNotification.cs:67). The ILogger interface takes (LogLevel, string, ...) — not a Func<string> lambda. DotNetWorkQueue.Logging.LogLevel is a custom enum; Microsoft.Extensions.Logging.LogLevel is what ILogger expects. No Log(LogLevel, Func<string>) extension method exists anywhere in the DotNetWorkQueue.Logging namespace directory.

Action: Replace example with correct ILogger call:

notifications.Log.LogDebug("Cancel has been requested - aborting");

Or using LogLevel directly:

notifications.Log.Log(Microsoft.Extensions.Logging.LogLevel.Debug, "Cancel has been requested - aborting");

Severity: High


[ConsumerAsync.md] Line ~55

Wiki says:

notifications.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => "Cancel has been requested - aborting");

Source says: Same as Consumer.md — IWorkerNotification.Log is Microsoft.Extensions.Logging.ILogger. Lambda overload does not exist.

Action: Same fix as Consumer.md. Severity: High


[ConsumerLinq.md] Line ~50

Wiki says:

w.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => "Cancel has been requested - aborting");

(where w is the IWorkerNotification instance passed into the linq expression)

Source says: Same issue — ILogger does not accept Func<string> lambda, and DotNetWorkQueue.Logging.LogLevel is the wrong enum type.

Action: Update to w.Log.LogDebug("Cancel has been requested - aborting"); Severity: High


[ConsumerLinqAsync.md] Line ~55

Wiki says:

w.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => "Cancel has been requested - aborting");

Source says: Same issue as ConsumerLinq.md.

Action: Same fix. Severity: High


[Consumer.md] — ConsumerQueueNotifications parameter omitted from Start call

Wiki says:

queue.Start<SimpleMessage>(Handle);

Source says:

void Start<T>(Action<IReceivedMessage<T>, IWorkerNotification> workerAction, ConsumerQueueNotifications notifications)
    where T : class;

The Start method requires a second parameter ConsumerQueueNotifications notifications. The wiki example omits it entirely.

Action: Update example to pass ConsumerQueueNotifications (can be null or new ConsumerQueueNotifications()). The wiki must show the correct signature. Severity: Critical


[ConsumerAsync.md] — ConsumerQueueNotifications parameter omitted from Start call

Wiki says:

queue.Start<SimpleMessage>(Handle);

Source says:

void Start<T>(Func<IReceivedMessage<T>, IWorkerNotification, Task> workerAction, ConsumerQueueNotifications notifications)
    where T : class;

Same omission as Consumer.md.

Action: Update example to include ConsumerQueueNotifications second parameter. Severity: Critical


[Consumer.md] — Missing IWorkerNotification properties not mentioned

Wiki says: Describes only WorkerStopping, TransportSupportsRollback, and Log on IWorkerNotification.

Source says: IWorkerNotification also exposes:

  • IHeaders HeaderNames
  • IWorkerHeartBeatNotification HeartBeat
  • IMetrics Metrics
  • ActivitySource Tracer
  • A per-message cancellation token property

Action: Add a section listing all IWorkerNotification properties so users know the full surface area available in their handler. Severity: Medium


[ConsumerAsync.md] — Missing IWorkerNotification properties (same gap)

Wiki says: Same incomplete description of IWorkerNotification as Consumer.md. Source says: Same as above. Action: Same addition needed. Severity: Medium


[ProducerConfiguration.md] — Extremely thin; missing history opt-in

Wiki says: Only mentions TimeConfiguration link. Full content:

#### Producer configuration
All configuration settings should be set before sending the first message.
* [Time Configuration](...)

Source says: QueueProducerConfiguration (which inherits QueueConfigurationSend) also exposes TransportConfiguration, AdditionalConfiguration, and Headers. More importantly, history tracking is controlled via transport-level options (EnableHistory, HistoryOptions) which affect producer behavior (enqueue tracking). The MessageHistory wiki page documents these options but ProducerConfiguration.md does not link to it.

Action: Expand to list all configuration sections available on the producer: TransportConfiguration, AdditionalConfiguration, time config, and add a link to MessageHistory (consistent with how ConsumerConfiguration.md links to it). Severity: Medium


[ConsumerConfiguration.md] — Missing MessageError configuration link

Wiki says: Lists these links:

  • Time Configuration
  • Worker Configuration
  • HeartBeat Configuration
  • Message Expiration Configuration
  • Transport Configuration
  • Message History

Source says: QueueConsumerConfiguration constructor accepts IMessageErrorConfiguration messageErrorConfiguration (parameter description: "Configuration for if/when to delete messages in an error status"). This configuration section is not linked from the wiki page.

Action: Add a link to a MessageErrorConfiguration wiki page (or document inline) for the MessageError property. Severity: Medium


[ConsumerAsyncConfiguration.md] — Structurally complete but missing MessageError link

Wiki says: Lists Time, Worker, HeartBeat, Message Expiration, Transport, Task Scheduler configuration links.

Source says: Same QueueConsumerConfiguration is used for async consumers. The MessageError configuration gap applies here too. Additionally, ConsumerConfiguration.md links to MessageHistory but ConsumerAsyncConfiguration.md does not — both consumer types support history.

Action: Add MessageError configuration link and MessageHistory link to match ConsumerConfiguration.md. Severity: Medium


[ConsumerAsyncWorkGroup.md] — AddWorkGroup parameter name discrepancy

Wiki says:

var group = taskScheduler.AddWorkGroup("workGroupName", 1, 1);

Describes: "max concurrency level of 1 and a max queue size of 1"

Source says: The WorkGroup constructor in TaskScheduling/WorkGroup.cs takes (string name, int concurrencyLevel) — only two parameters. The source-level WorkGroup class does not show a third constructor parameter. The wiki's AddWorkGroup("workGroupName", 1, 1) call with 3 arguments may be calling an extension or scheduler method not captured in the core library file found, but the description "max queue size" is not reflected in the WorkGroup class properties (only Name and ConcurrencyLevel are defined).

Action: Verify ITaskScheduler.AddWorkGroup actual signature in the task scheduling assembly. If the third parameter no longer exists, update the example to taskScheduler.AddWorkGroup("workGroupName", 1). Severity: High (needs source verification in task scheduling transport)


[Usage.md] — Incomplete listing of queue variants

Wiki says: Lists only 3 variants:

  • Producer
  • Consumer
  • ConsumerAsync

Source says: The library exposes additional variants documented in the wiki itself:

  • ProducerLinq (IProducerMethodQueue / CreateMethodProducer)
  • ConsumerLinq (IConsumerMethodQueue / CreateMethodConsumer)
  • ConsumerLinqAsync (linq method consumer with scheduler)
  • ConsumerAsyncWorkGroup (work group scheduler variant)

Action: Add links to ProducerLinq, ConsumerLinq, ConsumerLinqAsync, and ConsumerAsyncWorkGroup on the Usage.md page. These queue types are fully documented in the wiki but invisible from the Usage landing page. Severity: High


[MessageHistory.md] — EnableHistory not connected to consumer/producer configuration pages

Wiki says: Documents EnableHistory, HistoryOptions (with TrackEnqueue, TrackProcessing, TrackComplete, TrackError, TrackDelete, TrackExpire, MaxAgeMinutes, TruncateException, StoreBody, MonitorTime). States these are transport-level options.

Source says: The source confirms this — EnableHistory lives on IBaseTransportOptions/IHistoryTransportOptions. ConsumerConfiguration.md links to MessageHistory but ProducerConfiguration.md does not, even though TrackEnqueue fires on the producer path (confirmed by SendMessagesHistoryDecorator.cs).

Action: ProducerConfiguration.md must link to MessageHistory. The MessageHistory.md page itself is accurate. Severity: Medium (duplicate of ProducerConfiguration finding above — same fix)


[ProducerLinq.md] — Send with compiled expression: correct

Wiki says:

queue.Send((message, workerNotification) => Console.WriteLine(message.MessageId.Id.Value));

Source says: IProducerMethodQueue.Send(Expression<Action<IReceivedMessage<MessageExpression>, IWorkerNotification>> method, ...) — the lambda signature matches exactly. Action: No change needed. Severity: N/A (confirmed correct)


[ProducerLinq.md] — Send with LinqExpressionToRun: correct

Wiki says: Shows new LinqExpressionToRun(...) with string expression, assembly references, and using statements. Source says: IProducerMethodQueue has an overload accepting LinqExpressionToRun. Pattern is consistent with source. Action: No change needed. Severity: N/A (confirmed correct)


[Producer.md] — Factory method CreateProducer<T> correct

Wiki says: queueContainer.CreateProducer<YourMessageClass>(queueConnection) Source says: QueueContainer exposes CreateProducer<TMessage>. Pattern is valid. Action: No change needed. Severity: N/A (confirmed correct)


[ProducerLinq.md] — Factory method CreateMethodProducer correct

Wiki says: queueContainer.CreateMethodProducer(queueConnection) Source says: Consistent with IProducerMethodQueue usage. Valid. Action: No change needed. Severity: N/A (confirmed correct)


[ConsumerLinq.md] — Factory method CreateMethodConsumer correct

Wiki says: queueContainer.CreateMethodConsumer(queueConnection) Source says: Consistent with IConsumerMethodQueue.Start(ConsumerQueueNotifications). The Start() call in the wiki passes no arguments — which is correct because IConsumerMethodQueue.Start(ConsumerQueueNotifications notifications) still requires the notifications parameter.

Wiki says:

queue.Start();

Source says:

void Start(ConsumerQueueNotifications notifications);

The wiki omits the required ConsumerQueueNotifications parameter.

Action: Update queue.Start() to queue.Start(notifications) (or queue.Start(null)). Severity: Critical


Critical Findings Summary

# File Issue
1 Consumer.md Start<T> missing ConsumerQueueNotifications parameter
2 ConsumerAsync.md Start<T> missing ConsumerQueueNotifications parameter
3 ConsumerLinq.md Start() missing ConsumerQueueNotifications parameter

High Findings Summary

# File Issue
4 Consumer.md notifications.Log.Log(DotNetWorkQueue.Logging.LogLevel, Func<string>) — wrong API
5 ConsumerAsync.md Same broken logging pattern
6 ConsumerLinq.md Same broken logging pattern (w.Log.Log(...))
7 ConsumerLinqAsync.md Same broken logging pattern
8 Usage.md ProducerLinq, ConsumerLinq, ConsumerLinqAsync, WorkGroup variants not listed
9 ConsumerAsyncWorkGroup.md AddWorkGroup third parameter needs source verification

Medium Findings Summary

# File Issue
10 ProducerConfiguration.md Extremely thin; missing TransportConfiguration, AdditionalConfiguration, MessageHistory links
11 ConsumerConfiguration.md Missing MessageError configuration link
12 ConsumerAsyncConfiguration.md Missing MessageError and MessageHistory links
13 Consumer.md / ConsumerAsync.md IWorkerNotification property surface not fully documented

Clone this wiki locally