Skip to content

PLAN 2.1

Brian Lehnen edited this page Apr 8, 2026 · 1 revision

phase: 02-core-usage plan: "2.1" wave: 2 dependencies: ["1.1"] must_haves:

  • Consumer.md code sample includes ConsumerQueueNotifications as second param to Start()
  • Consumer.md logging uses Microsoft.Extensions.Logging ILogger methods (LogInformation, LogError, etc.)
  • ConsumerAsync.md code sample includes ConsumerQueueNotifications as second param to Start()
  • ConsumerAsync.md logging uses Microsoft.Extensions.Logging ILogger methods
  • No page contains DotNetWorkQueue.Logging.LogLevel or Log.Log( pattern files_touched:
  • Consumer.md
  • ConsumerAsync.md tdd: false

Plan 2.1 -- Consumer and ConsumerAsync Critical Fixes

Wave 2 -- Consumer pages. Depends on Plan 1.1 (sidebar renames complete). These two pages have the highest-severity findings: missing ConsumerQueueNotifications parameter on Start() and broken logging API.


Task 1: Fix Consumer.md -- verify Start() signature and logging API

`Consumer.md` was already partially updated in a prior session. Verify the current content is correct against the source API. The page should already have:
  1. queue.Start<SimpleMessage>(HandleMessages, notifications) with ConsumerQueueNotifications as second param
  2. ConsumerQueueNotifications constructed with 6 callback delegates
  3. notifications.Log.LogDebug(...) / LogInformation(...) / LogError(...) pattern (MEL)
  4. IWorkerNotification properties table including Log as ILogger, Metrics as IMetrics, Tracer as ActivitySource
  5. No references to DotNetWorkQueue.Logging.LogLevel or notifications.Log.Log( pattern

If the current page already matches all 5 checks, no edits are needed -- just verify and move on.

If any check fails, apply these corrections:

  • Start() signature must be: void Start<T>(Action<IReceivedMessage<T>, IWorkerNotification> workerAction, ConsumerQueueNotifications notifications)
  • Handler signature must be: private void HandleMessages(IReceivedMessage<SimpleMessage> message, IWorkerNotification notifications)
  • Logging must use: notifications.Log.LogDebug(...), notifications.Log.LogInformation(...), etc.
  • Remove any using DotNetWorkQueue.Logging; references
  • Ensure using DotNetWorkQueue.Queue; and using Microsoft.Extensions.Logging; are mentioned

Add a link to the samples repo at the bottom of the "Creating the queue" section if not present: > For a complete working example, see [SQLServerConsumer](https://github.com/blehnen/DotNetWorkQueue.Samples) in the samples repository.

grep -c "DotNetWorkQueue.Logging.LogLevel|Log.Log(" /mnt/f/git/dotnetworkqueue.wiki/Consumer.md; echo "---"; grep -c "ConsumerQueueNotifications" /mnt/f/git/dotnetworkqueue.wiki/Consumer.md; echo "---"; grep -c "LogInformation|LogError|LogDebug|LogWarning" /mnt/f/git/dotnetworkqueue.wiki/Consumer.md First grep returns 0 (no broken logging pattern). Second grep returns >= 2 (ConsumerQueueNotifications appears in both code sample and explanatory text). Third grep returns >= 2 (MEL methods used in logging section).

Task 2: Fix ConsumerAsync.md -- add ConsumerQueueNotifications and fix logging

`ConsumerAsync.md` was already partially updated. Verify and correct the following:
  1. Creation path: Uses CreateConsumerQueueScheduler(queueConnection, factory) -- this is the scheduler-based async consumer. The page should show the SchedulerContainer + TaskScheduler + TaskFactory setup pattern.

  2. Start() call: Must pass ConsumerQueueNotifications:

    queue.Start<SimpleMessage>(Handle, notifications);

    where notifications is constructed from new ConsumerQueueNotifications(...) with 6 callbacks.

  3. Handler signature: Must be Func<..., Task> for the direct IConsumerQueueAsync path, OR Action<...> for the scheduler-based IConsumerQueueScheduler path. The current page uses the scheduler path, so the handler is:

    private void Handle(IReceivedMessage<SimpleMessage> m, IWorkerNotification n)

    This is correct for CreateConsumerQueueScheduler.

  4. Logging: Verify no DotNetWorkQueue.Logging.LogLevel or Log.Log( pattern exists. If the cancellation example uses logging, it should use notifications.Log.LogDebug("Cancel has been requested - aborting").

  5. Scheduler dispose note: Verify the page mentions disposing the scheduler after all queues are disposed.

  6. Add a note clarifying the distinction: "This page demonstrates the scheduler-based async consumer (CreateConsumerQueueScheduler), which manages a thread pool via TaskScheduler. For the lower-level CreateConsumerAsync API where you manage tasks yourself, the same Start() pattern applies but the worker action must return Task."

  7. Add samples link at the bottom of the "Creating the queue" section: > For a complete working example, see [SQLServerConsumerAsync](https://github.com/blehnen/DotNetWorkQueue.Samples) in the samples repository.

grep -c "DotNetWorkQueue\.Logging\.LogLevel\|Log\.Log(" /mnt/f/git/dotnetworkqueue.wiki/ConsumerAsync.md; echo "---"; grep -c "ConsumerQueueNotifications" /mnt/f/git/dotnetworkqueue.wiki/ConsumerAsync.md; echo "---"; grep -c "CreateConsumerQueueScheduler\|SchedulerContainer" /mnt/f/git/dotnetworkqueue.wiki/ConsumerAsync.md First grep returns 0 (no broken logging). Second grep returns >= 2 (notifications in code + text). Third grep returns >= 1 (scheduler-based creation shown).

Task 3: Rename Linq pages to Method pages and delete old files

**Create three new files and delete three old files.** Per CONTEXT-2.md decision: delete old files entirely, no redirect stubs.

A) Create ProducerMethod.md based on current ProducerLinq.md content with these changes:

  • Title: "Producing Method Expressions" (not "Producing Linq statements")
  • Remove the entire "Send a dynamic statement, expressed as a string" section (lines 13-17 of current ProducerLinq.md) -- LinqExpressionToRun is #if net48 only, dead code on net8.0/net10.0
  • Replace "Linq statement" with "lambda expression" or "method expression" throughout
  • Replace "Unlike the POCO queues" with "Unlike the typed-message producer"
  • Keep CreateMethodProducer(queueConnection) creation code (already correct)
  • Keep all Send/SendAsync examples (lambda format is correct)
  • Add samples link: > For a complete working example, see [SQLServerProducerLinq](https://github.com/blehnen/DotNetWorkQueue.Samples) in the samples repository.

B) Create ConsumerMethod.md based on current ConsumerLinq.md content with these changes:

  • Title: "Consuming Method Expressions" (not "Consuming Linq Statements")
  • Replace "Linq" / "linq" with "method expression" or "lambda expression" throughout
  • Opening line: link to ConsumerMethodAsync instead of ConsumerLinqAsync
  • The code sample already uses CreateConsumerMethodQueueScheduler and queue.Start(notifications) -- this is correct
  • Verify ConsumerQueueNotifications is present in the code sample (it is in current ConsumerLinq.md)
  • Replace "POCO queue" with "typed-message consumer"
  • Remove any reference to dynamic LINQ or LinqExpressionToRun
  • Verify logging uses MEL pattern (current page uses logger.LogError, logger.LogWarning, logger.LogInformation -- these are correct)
  • Add samples link: > For a complete working example, see [SQLServerConsumerLinq](https://github.com/blehnen/DotNetWorkQueue.Samples) in the samples repository.

C) Create ConsumerMethodAsync.md based on current ConsumerLinqAsync.md content with these changes:

  • Title: "Consuming Method Expressions (Async)" (not "Consuming messages")
  • Opening line: link to ConsumerMethod instead of ConsumerLinq
  • Replace all "Linq" / "linq" references with "method expression" or "lambda expression"
  • The code sample already uses CreateConsumerMethodQueueScheduler -- correct
  • Verify ConsumerQueueNotifications is present in the code sample (it is in current ConsumerLinqAsync.md)
  • Fix factory.scheduler to factory.Scheduler (capital S) on lines 21-23 if not already fixed
  • Replace "When your linq statement finishes" with "When your method expression finishes"
  • Add samples link: > For a complete working example, see [SQLServerConsumerLinq](https://github.com/blehnen/DotNetWorkQueue.Samples) in the samples repository.

D) Delete old files:

  • rm ProducerLinq.md
  • rm ConsumerLinq.md
  • rm ConsumerLinqAsync.md
ls /mnt/f/git/dotnetworkqueue.wiki/ProducerMethod.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerMethod.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerMethodAsync.md 2>&1; echo "---"; ls /mnt/f/git/dotnetworkqueue.wiki/ProducerLinq.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerLinq.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerLinqAsync.md 2>&1; echo "---"; grep -c "LinqExpressionToRun\|dynamic statement\|dynamic linq" /mnt/f/git/dotnetworkqueue.wiki/ProducerMethod.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerMethod.md /mnt/f/git/dotnetworkqueue.wiki/ConsumerMethodAsync.md New files exist (first ls succeeds). Old files do not exist (second ls returns "No such file" for all three). Third grep returns 0 for all files (no dynamic LINQ references).

Clone this wiki locally