diff --git a/src/StackExchange.Redis/PhysicalBridge.cs b/src/StackExchange.Redis/PhysicalBridge.cs index 6036c561a..b98b1746c 100644 --- a/src/StackExchange.Redis/PhysicalBridge.cs +++ b/src/StackExchange.Redis/PhysicalBridge.cs @@ -701,6 +701,14 @@ internal WriteResult WriteMessageTakingWriteLockSync(PhysicalConnection physical Trace("Writing: " + message); message.SetEnqueued(physical); // this also records the read/write stats at this point + // AVOID REORDERING MESSAGES + // Prefer to add it to the backlog if this thread can see that there might already be a message backlog. + // We do this before attempting to take the writelock, because we won't actually write, we'll just let the backlog get processed in due course + if (PushToBacklog(message, onlyIfExists: true)) + { + return WriteResult.Success; // queued counts as success + } + LockToken token = default; try { @@ -978,11 +986,20 @@ internal ValueTask WriteMessageTakingWriteLockAsync(PhysicalConnect Trace("Writing: " + message); message.SetEnqueued(physical); // this also records the read/write stats at this point + // AVOID REORDERING MESSAGES + // Prefer to add it to the backlog if this thread can see that there might already be a message backlog. + // We do this before attempting to take the writelock, because we won't actually write, we'll just let the backlog get processed in due course + if (PushToBacklog(message, onlyIfExists: true)) + { + return new ValueTask(WriteResult.Success); // queued counts as success + } + bool releaseLock = true; // fine to default to true, as it doesn't matter until token is a "success" int lockTaken = 0; LockToken token = default; try { + // try to acquire it synchronously // note: timeout is specified in mutex-constructor token = _singleWriterMutex.TryWait(options: WaitOptions.NoDelay);