Commit d5024f5e authored by Marc Gravell's avatar Marc Gravell

transactions: don't log the connect crap; use a StringBuilder to buffer the...

transactions: don't log the connect crap; use a StringBuilder to buffer the tran log to avoid lots of sync blocks
parent d86195d2
using System; using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
...@@ -9,6 +10,13 @@ namespace StackExchange.Redis.Tests ...@@ -9,6 +10,13 @@ namespace StackExchange.Redis.Tests
{ {
public class Transactions : TestBase public class Transactions : TestBase
{ {
protected override ConnectionMultiplexer Create(string clientName = null, int? syncTimeout = null, bool? allowAdmin = null, int? keepAlive = null, int? connectTimeout = null, string password = null, string tieBreaker = null, TextWriter log = null, bool fail = true, string[] disabledCommands = null, string[] enabledCommands = null, bool checkConnect = true, string failMessage = null, string channelPrefix = null, Proxy? proxy = null, string configuration = null, [CallerMemberName] string caller = null)
{
return base.Create(clientName, syncTimeout, allowAdmin, keepAlive, connectTimeout, password, tieBreaker,
TextWriter.Null, // <== the one I care about
fail, disabledCommands, enabledCommands, checkConnect, failMessage, channelPrefix, proxy, configuration, caller);
}
public Transactions(ITestOutputHelper output) : base(output) { } public Transactions(ITestOutputHelper output) : base(output) { }
[Fact] [Fact]
...@@ -764,7 +772,7 @@ public async Task BasicTranWithSortedSetContainsCondition(bool demandKeyExists, ...@@ -764,7 +772,7 @@ public async Task BasicTranWithSortedSetContainsCondition(bool demandKeyExists,
[InlineData("", ComparisonType.GreaterThan, 0L, false)] [InlineData("", ComparisonType.GreaterThan, 0L, false)]
public async Task BasicTranWithListLengthCondition(string value, ComparisonType type, long length, bool expectTranResult) public async Task BasicTranWithListLengthCondition(string value, ComparisonType type, long length, bool expectTranResult)
{ {
using (var muxer = Create(log: TextWriter.Null)) using (var muxer = Create())
{ {
RedisKey key = Me(), key2 = Me() + "2"; RedisKey key = Me(), key2 = Me() + "2";
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
...@@ -903,7 +911,7 @@ public async Task ParallelTransactionsWithConditions() ...@@ -903,7 +911,7 @@ public async Task ParallelTransactionsWithConditions()
try try
{ {
for (int i = 0; i < Muxers; i++) for (int i = 0; i < Muxers; i++)
muxers[i] = Create(log: TextWriter.Null); muxers[i] = Create();
RedisKey hits = Me(), trigger = Me() + "3"; RedisKey hits = Me(), trigger = Me() + "3";
int expectedSuccess = 0; int expectedSuccess = 0;
...@@ -958,8 +966,8 @@ public async Task ParallelTransactionsWithConditions() ...@@ -958,8 +966,8 @@ public async Task ParallelTransactionsWithConditions()
[Fact] [Fact]
public async Task WatchAbort_StringEqual() public async Task WatchAbort_StringEqual()
{ {
using (var vic = Create(log: TextWriter.Null)) using (var vic = Create())
using (var perp = Create(log: TextWriter.Null)) using (var perp = Create())
{ {
var key = Me(); var key = Me();
var db = vic.GetDatabase(); var db = vic.GetDatabase();
...@@ -983,8 +991,8 @@ public async Task WatchAbort_StringEqual() ...@@ -983,8 +991,8 @@ public async Task WatchAbort_StringEqual()
[Fact] [Fact]
public async Task WatchAbort_HashLengthEqual() public async Task WatchAbort_HashLengthEqual()
{ {
using (var vic = Create(log: TextWriter.Null)) using (var vic = Create())
using (var perp = Create(log: TextWriter.Null)) using (var perp = Create())
{ {
var key = Me(); var key = Me();
var db = vic.GetDatabase(); var db = vic.GetDatabase();
......
...@@ -233,6 +233,9 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -233,6 +233,9 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
bool explicitCheckForQueued = !bridge.ServerEndPoint.GetFeatures().ExecAbort; bool explicitCheckForQueued = !bridge.ServerEndPoint.GetFeatures().ExecAbort;
var multiplexer = bridge.Multiplexer; var multiplexer = bridge.Multiplexer;
var sb = new StringBuilder();
try
{
try try
{ {
// Important: if the server supports EXECABORT, then we can check the pre-conditions (pause there), // Important: if the server supports EXECABORT, then we can check the pre-conditions (pause there),
...@@ -246,7 +249,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -246,7 +249,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
// PART 1: issue the pre-conditions // PART 1: issue the pre-conditions
if (!IsAborted && conditions.Length != 0) if (!IsAborted && conditions.Length != 0)
{ {
multiplexer.OnTransactionLog($"issuing conditions..."); sb.AppendLine($"issuing conditions...");
int cmdCount = 0; int cmdCount = 0;
for (int i = 0; i < conditions.Length; i++) for (int i = 0; i < conditions.Length; i++)
{ {
...@@ -260,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -260,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{ {
msg.SetNoRedirect(); // need to keep them in the current context only msg.SetNoRedirect(); // need to keep them in the current context only
yield return msg; yield return msg;
multiplexer.OnTransactionLog($"issuing {msg.CommandAndKey}"); sb.AppendLine($"issuing {msg.CommandAndKey}");
cmdCount++; cmdCount++;
} }
} }
multiplexer.OnTransactionLog($"issued {conditions.Length} conditions ({cmdCount} commands)"); sb.AppendLine($"issued {conditions.Length} conditions ({cmdCount} commands)");
if (!explicitCheckForQueued && lastBox != null) if (!explicitCheckForQueued && lastBox != null)
{ {
multiplexer.OnTransactionLog($"checking conditions in the *early* path"); sb.AppendLine($"checking conditions in the *early* path");
// need to get those sent ASAP; if they are stuck in the buffers, we die // need to get those sent ASAP; if they are stuck in the buffers, we die
multiplexer.Trace("Flushing and waiting for precondition responses"); multiplexer.Trace("Flushing and waiting for precondition responses");
connection.FlushAsync().Wait(); connection.FlushAsync().Wait();
...@@ -277,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -277,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!AreAllConditionsSatisfied(multiplexer)) if (!AreAllConditionsSatisfied(multiplexer))
command = RedisCommand.UNWATCH; // somebody isn't happy command = RedisCommand.UNWATCH; // somebody isn't happy
multiplexer.OnTransactionLog($"after condition check, we are {command}"); sb.AppendLine($"after condition check, we are {command}");
} }
else else
{ // timeout running pre-conditions { // timeout running pre-conditions
multiplexer.Trace("Timeout checking preconditions"); multiplexer.Trace("Timeout checking preconditions");
command = RedisCommand.UNWATCH; command = RedisCommand.UNWATCH;
multiplexer.OnTransactionLog($"timeout waiting for conditions, we are {command}"); sb.AppendLine($"timeout waiting for conditions, we are {command}");
} }
Monitor.Exit(lastBox); Monitor.Exit(lastBox);
lastBox = null; lastBox = null;
...@@ -296,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -296,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{ {
multiplexer.Trace("Begining transaction"); multiplexer.Trace("Begining transaction");
yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI); yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI);
multiplexer.OnTransactionLog($"issued MULTI"); sb.AppendLine($"issued MULTI");
} }
// PART 3: issue the commands // PART 3: issue the commands
...@@ -318,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -318,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
} }
yield return op; yield return op;
multiplexer.OnTransactionLog($"issued {op.CommandAndKey}"); sb.AppendLine($"issued {op.CommandAndKey}");
} }
multiplexer.OnTransactionLog($"issued {InnerOperations.Length} operations"); sb.AppendLine($"issued {InnerOperations.Length} operations");
if (explicitCheckForQueued && lastBox != null) if (explicitCheckForQueued && lastBox != null)
{ {
multiplexer.OnTransactionLog($"checking conditions in the *late* path"); sb.AppendLine($"checking conditions in the *late* path");
multiplexer.Trace("Flushing and waiting for precondition+queued responses"); multiplexer.Trace("Flushing and waiting for precondition+queued responses");
connection.FlushAsync().Wait(); // make sure they get sent, so we can check for QUEUED (and the pre-conditions if necessary) connection.FlushAsync().Wait(); // make sure they get sent, so we can check for QUEUED (and the pre-conditions if necessary)
...@@ -341,20 +344,20 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -341,20 +344,20 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!op.WasQueued) if (!op.WasQueued)
{ {
multiplexer.Trace("Aborting: operation was not queued: " + op.Command); multiplexer.Trace("Aborting: operation was not queued: " + op.Command);
multiplexer.OnTransactionLog($"command was not issued: {op.CommandAndKey}"); sb.AppendLine($"command was not issued: {op.CommandAndKey}");
command = RedisCommand.DISCARD; command = RedisCommand.DISCARD;
break; break;
} }
} }
} }
multiplexer.Trace("Confirmed: QUEUED x " + InnerOperations.Length); multiplexer.Trace("Confirmed: QUEUED x " + InnerOperations.Length);
multiplexer.OnTransactionLog($"after condition check, we are {command}"); sb.AppendLine($"after condition check, we are {command}");
} }
else else
{ {
multiplexer.Trace("Aborting: timeout checking queued messages"); multiplexer.Trace("Aborting: timeout checking queued messages");
command = RedisCommand.DISCARD; command = RedisCommand.DISCARD;
multiplexer.OnTransactionLog($"timeout waiting for conditions, we are {command}"); sb.AppendLine($"timeout waiting for conditions, we are {command}");
} }
Monitor.Exit(lastBox); Monitor.Exit(lastBox);
lastBox = null; lastBox = null;
...@@ -367,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -367,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
if (IsAborted) if (IsAborted)
{ {
multiplexer.OnTransactionLog($"aborting {InnerOperations.Length} wrapped commands..."); sb.AppendLine($"aborting {InnerOperations.Length} wrapped commands...");
connection.Trace("Aborting: canceling wrapped messages"); connection.Trace("Aborting: canceling wrapped messages");
foreach (var op in InnerOperations) foreach (var op in InnerOperations)
{ {
...@@ -376,9 +379,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -376,9 +379,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
} }
connection.Trace("End of transaction: " + Command); connection.Trace("End of transaction: " + Command);
multiplexer.OnTransactionLog($"issuing {Command}"); sb.AppendLine($"issuing {Command}");
yield return this; // acts as either an EXEC or an UNWATCH, depending on "aborted" yield return this; // acts as either an EXEC or an UNWATCH, depending on "aborted"
} }
finally
{
multiplexer.OnTransactionLog(sb.ToString());
}
}
protected override void WriteImpl(PhysicalConnection physical) protected override void WriteImpl(PhysicalConnection physical)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment