Skip to content

[Host] Semaphore leak in ConcurrentMessageProcessorDecorator<TMessage>.ProcessMessage causes stalled consumers #438

@MaxNau

Description

@MaxNau

Problem

User perspective

If message deserialization fails (invalid JSON schema) or user returns ProcessResult.Failure in error handler the consumer is stuck. No messages after failure arrive.

Tech perspective

ProcessMessage acquires the _concurrentSemaphore then returns early when a saved _lastException exists - but it does not release the semaphore. Repeatedly hitting this path leaks semaphore slots and eventually stalls message processing.

Repository / file

• SlimMessageBus.Host\Consumer\MessageProcessors\ConcurrentMessageProcessorDecorator.cs
• Affects methods: ProcessMessage, ProcessInBackground

Steps to reproduce

  1. Configure a consumer with low concurrency (e.g. 1).
  2. Cause a background ProcessInBackground to produce a ProcessMessageResult with Exception != null.
  3. Call ProcessMessage — it will WaitAsync, observe _lastException, return Failure and never release the semaphore.
  4. Repeat until all semaphore slots are consumed; processing stalls.

Actual behavior

Semaphore slots are not released on the early-return path and capacity is exhausted, stalling message processing.

Expected behavior

When returning early due to a saved exception, the semaphore must be released before returning so slots are not leaked.

Root cause

Early-return after await _concurrentSemaphore.WaitAsync(...) without a corresponding Release() — normal Release() runs only in ProcessInBackground finally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions