Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IProfiledCommand data expansion #1454

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/StackExchange.Redis/Interfaces/IKeysMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace StackExchange.Redis
{
internal interface IKeysMessage
{
RedisKey[] Keys { get; }
}
}
7 changes: 7 additions & 0 deletions src/StackExchange.Redis/Interfaces/IValuesMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace StackExchange.Redis
{
internal interface IValuesMessage
{
RedisValue[] Values { get; }
}
}
110 changes: 65 additions & 45 deletions src/StackExchange.Redis/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -795,10 +795,12 @@ protected CommandChannelBase(int db, CommandFlags flags, RedisCommand command, i
public override string CommandAndKey => Command + " " + Channel;
}

internal abstract class CommandKeyBase : Message
internal abstract class CommandKeyBase : Message, IKeysMessage
{
protected readonly RedisKey Key;

public virtual RedisKey[] Keys => new RedisKey[] { Key };

protected CommandKeyBase(int db, CommandFlags flags, RedisCommand command, in RedisKey key) : base(db, flags, command)
{
key.AssertNotNull();
Expand All @@ -825,9 +827,12 @@ protected override void WriteImpl(PhysicalConnection physical)
public override int ArgCount => 1;
}

private sealed class CommandChannelValueMessage : CommandChannelBase
private sealed class CommandChannelValueMessage : CommandChannelBase, IValuesMessage
{
private readonly RedisValue value;

public RedisValue[] Values => new RedisValue[] { value };

public CommandChannelValueMessage(int db, CommandFlags flags, RedisCommand command, in RedisChannel channel, in RedisValue value) : base(db, flags, command, channel)
{
value.AssertNotNull();
Expand All @@ -846,6 +851,9 @@ protected override void WriteImpl(PhysicalConnection physical)
private sealed class CommandKeyKeyKeyMessage : CommandKeyBase
{
private readonly RedisKey key1, key2;

public override RedisKey[] Keys => new RedisKey[] { Key, key1, key2 };

public CommandKeyKeyKeyMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key0, in RedisKey key1, in RedisKey key2) : base(db, flags, command, key0)
{
key1.AssertNotNull();
Expand Down Expand Up @@ -874,6 +882,9 @@ protected override void WriteImpl(PhysicalConnection physical)
private class CommandKeyKeyMessage : CommandKeyBase
{
protected readonly RedisKey key1;

public override RedisKey[] Keys => new RedisKey[] { Key, key1 };

public CommandKeyKeyMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key0, in RedisKey key1) : base(db, flags, command, key0)
{
key1.AssertNotNull();
Expand All @@ -897,36 +908,37 @@ protected override void WriteImpl(PhysicalConnection physical)

private sealed class CommandKeyKeysMessage : CommandKeyBase
{
private readonly RedisKey[] keys;
public override RedisKey[] Keys { get; }

public CommandKeyKeysMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key, RedisKey[] keys) : base(db, flags, command, key)
{
for (int i = 0; i < keys.Length; i++)
{
keys[i].AssertNotNull();
}
this.keys = keys;
Keys = keys;
}

public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
{
var slot = serverSelectionStrategy.HashSlot(Key);
for (int i = 0; i < keys.Length; i++)
for (int i = 0; i < Keys.Length; i++)
{
slot = serverSelectionStrategy.CombineSlot(slot, keys[i]);
slot = serverSelectionStrategy.CombineSlot(slot, Keys[i]);
}
return slot;
}

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(command, keys.Length + 1);
physical.WriteHeader(command, Keys.Length + 1);
physical.Write(Key);
for (int i = 0; i < keys.Length; i++)
for (int i = 0; i < Keys.Length; i++)
{
physical.Write(keys[i]);
physical.Write(Keys[i]);
}
}
public override int ArgCount => keys.Length + 1;
public override int ArgCount => Keys.Length + 1;
}

private sealed class CommandKeyKeyValueMessage : CommandKeyKeyMessage
Expand Down Expand Up @@ -961,60 +973,62 @@ protected override void WriteImpl(PhysicalConnection physical)
public override int ArgCount => 1;
}

private sealed class CommandValuesMessage : Message
private sealed class CommandValuesMessage : Message, IValuesMessage
{
private readonly RedisValue[] values;
public RedisValue[] Values { get; }

public CommandValuesMessage(int db, CommandFlags flags, RedisCommand command, RedisValue[] values) : base(db, flags, command)
{
for (int i = 0; i < values.Length; i++)
{
values[i].AssertNotNull();
}
this.values = values;
Values = values;
}

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(command, values.Length);
for (int i = 0; i < values.Length; i++)
physical.WriteHeader(command, Values.Length);
for (int i = 0; i < Values.Length; i++)
{
physical.WriteBulkString(values[i]);
physical.WriteBulkString(Values[i]);
}
}
public override int ArgCount => values.Length;
public override int ArgCount => Values.Length;
}

private sealed class CommandKeysMessage : Message
private sealed class CommandKeysMessage : Message, IKeysMessage
{
private readonly RedisKey[] keys;
public RedisKey[] Keys { get; }

public CommandKeysMessage(int db, CommandFlags flags, RedisCommand command, RedisKey[] keys) : base(db, flags, command)
{
for (int i = 0; i < keys.Length; i++)
{
keys[i].AssertNotNull();
}
this.keys = keys;
Keys = keys;
}

public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
{
int slot = ServerSelectionStrategy.NoSlot;
for (int i = 0; i < keys.Length; i++)
for (int i = 0; i < Keys.Length; i++)
{
slot = serverSelectionStrategy.CombineSlot(slot, keys[i]);
slot = serverSelectionStrategy.CombineSlot(slot, Keys[i]);
}
return slot;
}

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(command, keys.Length);
for (int i = 0; i < keys.Length; i++)
physical.WriteHeader(command, Keys.Length);
for (int i = 0; i < Keys.Length; i++)
{
physical.Write(keys[i]);
physical.Write(Keys[i]);
}
}
public override int ArgCount => keys.Length;
public override int ArgCount => Keys.Length;
}

private sealed class CommandKeyValueMessage : CommandKeyBase
Expand All @@ -1035,17 +1049,21 @@ protected override void WriteImpl(PhysicalConnection physical)
public override int ArgCount => 2;
}

private sealed class CommandKeyValuesKeyMessage : CommandKeyBase
private sealed class CommandKeyValuesKeyMessage : CommandKeyBase, IKeysMessage, IValuesMessage
{
private readonly RedisKey key1;
private readonly RedisValue[] values;

public override RedisKey[] Keys => new RedisKey[] { Key, key1 };

public RedisValue[] Values { get; }

public CommandKeyValuesKeyMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key0, RedisValue[] values, in RedisKey key1) : base(db, flags, command, key0)
{
for (int i = 0; i < values.Length; i++)
{
values[i].AssertNotNull();
}
this.values = values;
Values = values;
key1.AssertNotNull();
this.key1 = key1;
}
Expand All @@ -1058,33 +1076,34 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(Command, values.Length + 2);
physical.WriteHeader(Command, Values.Length + 2);
physical.Write(Key);
for (int i = 0; i < values.Length; i++) physical.WriteBulkString(values[i]);
for (int i = 0; i < Values.Length; i++) physical.WriteBulkString(Values[i]);
physical.Write(key1);
}
public override int ArgCount => values.Length + 2;
public override int ArgCount => Values.Length + 2;
}

private sealed class CommandKeyValuesMessage : CommandKeyBase
private sealed class CommandKeyValuesMessage : CommandKeyBase, IValuesMessage
{
private readonly RedisValue[] values;
public RedisValue[] Values { get; }

public CommandKeyValuesMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key, RedisValue[] values) : base(db, flags, command, key)
{
for (int i = 0; i < values.Length; i++)
{
values[i].AssertNotNull();
}
this.values = values;
Values = values;
}

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(Command, values.Length + 1);
physical.WriteHeader(Command, Values.Length + 1);
physical.Write(Key);
for (int i = 0; i < values.Length; i++) physical.WriteBulkString(values[i]);
for (int i = 0; i < Values.Length; i++) physical.WriteBulkString(Values[i]);
}
public override int ArgCount => values.Length + 1;
public override int ArgCount => Values.Length + 1;
}

private sealed class CommandKeyValueValueMessage : CommandKeyBase
Expand Down Expand Up @@ -1169,10 +1188,11 @@ protected override void WriteImpl(PhysicalConnection physical)
public override int ArgCount => 0;
}

private class CommandSlotValuesMessage : Message
private class CommandSlotValuesMessage : Message, IValuesMessage
{
private readonly int slot;
private readonly RedisValue[] values;

public RedisValue[] Values { get; }

public CommandSlotValuesMessage(int db, int slot, CommandFlags flags, RedisCommand command, RedisValue[] values)
: base(db, flags, command)
Expand All @@ -1182,7 +1202,7 @@ public CommandSlotValuesMessage(int db, int slot, CommandFlags flags, RedisComma
{
values[i].AssertNotNull();
}
this.values = values;
Values = values;
}

public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
Expand All @@ -1192,13 +1212,13 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)

protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(command, values.Length);
for (int i = 0; i < values.Length; i++)
physical.WriteHeader(command, Values.Length);
for (int i = 0; i < Values.Length; i++)
{
physical.WriteBulkString(values[i]);
physical.WriteBulkString(Values[i]);
}
}
public override int ArgCount => values.Length;
public override int ArgCount => Values.Length;
}

private sealed class CommandValueChannelMessage : CommandChannelBase
Expand Down
17 changes: 16 additions & 1 deletion src/StackExchange.Redis/Profiling/IProfiledCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,26 @@ public interface IProfiledCommand
/// </summary>
string Command { get; }

/// <summary>
/// The name of the script when EVAL command is issued.
/// </summary>
string Script { get; }
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// The keys supplied on the command, if any.
/// </summary>
RedisKey[] Keys { get; }

/// <summary>
/// The CommandFlags the command was submitted with.
/// </summary>
CommandFlags Flags { get; }

/// <summary>
/// The values returned by the command, if any.
/// </summary>
RedisValue[] Values { get; }

/// <summary>
/// <para>
/// When this command was *created*, will be approximately
Expand Down Expand Up @@ -85,7 +100,7 @@ public interface IProfiledCommand
/// <summary>
/// If RetransmissionOf is not null, this property will be set to either Ask or Moved to indicate
/// what sort of response triggered the retransmission.
///
///
/// This can be useful for determining the root cause of extra commands.
/// </summary>
RetransmissionReasonType? RetransmissionReason { get; }
Expand Down
6 changes: 6 additions & 0 deletions src/StackExchange.Redis/Profiling/ProfiledCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ internal sealed class ProfiledCommand : IProfiledCommand

public string Command => Message is RedisDatabase.ExecuteMessage em ? em.Command.ToString() : Message.Command.ToString();

public string Script => Message is RedisDatabase.ScriptEvalMessage sem ? sem.Script : null;

public RedisKey[] Keys => Message is IKeysMessage km ? km.Keys : null;

public CommandFlags Flags => Message.Flags;

public RedisValue[] Values => Message is IValuesMessage vm ? vm.Values : null;

public DateTime CommandCreated => MessageCreatedDateTime;

public TimeSpan CreationToEnqueued => GetElapsedTime(EnqueuedTimeStamp - MessageCreatedTimeStamp);
Expand Down