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.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
......@@ -9,6 +10,13 @@ namespace StackExchange.Redis.Tests
{
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) { }
[Fact]
......@@ -764,7 +772,7 @@ public async Task BasicTranWithSortedSetContainsCondition(bool demandKeyExists,
[InlineData("", ComparisonType.GreaterThan, 0L, false)]
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";
var db = muxer.GetDatabase();
......@@ -903,7 +911,7 @@ public async Task ParallelTransactionsWithConditions()
try
{
for (int i = 0; i < Muxers; i++)
muxers[i] = Create(log: TextWriter.Null);
muxers[i] = Create();
RedisKey hits = Me(), trigger = Me() + "3";
int expectedSuccess = 0;
......@@ -958,8 +966,8 @@ public async Task ParallelTransactionsWithConditions()
[Fact]
public async Task WatchAbort_StringEqual()
{
using (var vic = Create(log: TextWriter.Null))
using (var perp = Create(log: TextWriter.Null))
using (var vic = Create())
using (var perp = Create())
{
var key = Me();
var db = vic.GetDatabase();
......@@ -983,8 +991,8 @@ public async Task WatchAbort_StringEqual()
[Fact]
public async Task WatchAbort_HashLengthEqual()
{
using (var vic = Create(log: TextWriter.Null))
using (var perp = Create(log: TextWriter.Null))
using (var vic = Create())
using (var perp = Create())
{
var key = Me();
var db = vic.GetDatabase();
......
......@@ -233,6 +233,9 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
bool explicitCheckForQueued = !bridge.ServerEndPoint.GetFeatures().ExecAbort;
var multiplexer = bridge.Multiplexer;
var sb = new StringBuilder();
try
{
try
{
// 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)
// PART 1: issue the pre-conditions
if (!IsAborted && conditions.Length != 0)
{
multiplexer.OnTransactionLog($"issuing conditions...");
sb.AppendLine($"issuing conditions...");
int cmdCount = 0;
for (int i = 0; i < conditions.Length; i++)
{
......@@ -260,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{
msg.SetNoRedirect(); // need to keep them in the current context only
yield return msg;
multiplexer.OnTransactionLog($"issuing {msg.CommandAndKey}");
sb.AppendLine($"issuing {msg.CommandAndKey}");
cmdCount++;
}
}
multiplexer.OnTransactionLog($"issued {conditions.Length} conditions ({cmdCount} commands)");
sb.AppendLine($"issued {conditions.Length} conditions ({cmdCount} commands)");
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
multiplexer.Trace("Flushing and waiting for precondition responses");
connection.FlushAsync().Wait();
......@@ -277,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!AreAllConditionsSatisfied(multiplexer))
command = RedisCommand.UNWATCH; // somebody isn't happy
multiplexer.OnTransactionLog($"after condition check, we are {command}");
sb.AppendLine($"after condition check, we are {command}");
}
else
{ // timeout running pre-conditions
multiplexer.Trace("Timeout checking preconditions");
command = RedisCommand.UNWATCH;
multiplexer.OnTransactionLog($"timeout waiting for conditions, we are {command}");
sb.AppendLine($"timeout waiting for conditions, we are {command}");
}
Monitor.Exit(lastBox);
lastBox = null;
......@@ -296,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{
multiplexer.Trace("Begining transaction");
yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI);
multiplexer.OnTransactionLog($"issued MULTI");
sb.AppendLine($"issued MULTI");
}
// PART 3: issue the commands
......@@ -318,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
}
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)
{
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");
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)
if (!op.WasQueued)
{
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;
break;
}
}
}
multiplexer.Trace("Confirmed: QUEUED x " + InnerOperations.Length);
multiplexer.OnTransactionLog($"after condition check, we are {command}");
sb.AppendLine($"after condition check, we are {command}");
}
else
{
multiplexer.Trace("Aborting: timeout checking queued messages");
command = RedisCommand.DISCARD;
multiplexer.OnTransactionLog($"timeout waiting for conditions, we are {command}");
sb.AppendLine($"timeout waiting for conditions, we are {command}");
}
Monitor.Exit(lastBox);
lastBox = null;
......@@ -367,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
if (IsAborted)
{
multiplexer.OnTransactionLog($"aborting {InnerOperations.Length} wrapped commands...");
sb.AppendLine($"aborting {InnerOperations.Length} wrapped commands...");
connection.Trace("Aborting: canceling wrapped messages");
foreach (var op in InnerOperations)
{
......@@ -376,9 +379,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
}
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"
}
finally
{
multiplexer.OnTransactionLog(sb.ToString());
}
}
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