Commit 0ff068e9 authored by Nick Craver's avatar Nick Craver

Cleanup: Interfaces

Still a lot of docs work to follow-up with here.
parent 1a25068a
namespace StackExchange.Redis
{
/// <summary>
/// If an IProfiledCommand is a retransmission of a previous command, this enum
/// is used to indicate what prompted the retransmission.
///
/// This can be used to distinguish between transient causes (moving hashslots, joining nodes, etc.)
/// and incorrect routing.
/// </summary>
public enum RetransmissionReasonType
{
/// <summary>
/// No stated reason
/// </summary>
None = 0,
/// <summary>
/// Issued to investigate which node owns a key
/// </summary>
Ask,
/// <summary>
/// A node has indicated that it does *not* own the given key
/// </summary>
Moved
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
interface ICompletable internal interface ICompletable
{ {
void AppendStormLog(StringBuilder sb); void AppendStormLog(StringBuilder sb);
......
...@@ -10,7 +10,6 @@ namespace StackExchange.Redis ...@@ -10,7 +10,6 @@ namespace StackExchange.Redis
/// </summary> /// </summary>
public interface IConnectionMultiplexer public interface IConnectionMultiplexer
{ {
#if DEBUG #if DEBUG
/// <summary> /// <summary>
/// For debugging; when not enabled, servers cannot connect /// For debugging; when not enabled, servers cannot connect
......
using System; using System;
using System.Net; using System.Net;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
/// <summary> /// <summary>
/// If an IProfiledCommand is a retransmission of a previous command, this enum /// A profiled command against a redis instance.
/// is used to indicate what prompted the retransmission. ///
/// /// TimeSpans returned by this interface use a high precision timer if possible.
/// This can be used to distinguish between transient causes (moving hashslots, joining nodes, etc.) /// DateTimes returned by this interface are no more precise than DateTime.UtcNow.
/// and incorrect routing. /// </summary>
/// </summary> public interface IProfiledCommand
public enum RetransmissionReasonType {
{ /// <summary>
/// <summary> /// The endpoint this command was sent to.
/// No stated reason /// </summary>
/// </summary> EndPoint EndPoint { get; }
None = 0,
/// <summary> /// <summary>
/// Issued to investigate which node owns a key /// The Db this command was sent to.
/// </summary> /// </summary>
Ask, int Db { get; }
/// <summary>
/// A node has indicated that it does *not* own the given key /// <summary>
/// </summary> /// The name of this command.
Moved /// </summary>
} string Command { get; }
/// <summary> /// <summary>
/// A profiled command against a redis instance. /// The CommandFlags the command was submitted with.
/// /// </summary>
/// TimeSpans returned by this interface use a high precision timer if possible. CommandFlags Flags { get; }
/// DateTimes returned by this interface are no more precise than DateTime.UtcNow.
/// </summary> /// <summary>
public interface IProfiledCommand /// When this command was *created*, will be approximately
{ /// when the paired method of StackExchange.Redis was called but
/// <summary> /// before that method returned.
/// The endpoint this command was sent to. ///
/// </summary> /// Note that the resolution of the returned DateTime is limited by DateTime.UtcNow.
EndPoint EndPoint { get; } /// </summary>
DateTime CommandCreated { get; }
/// <summary>
/// The Db this command was sent to. /// <summary>
/// </summary> /// How long this command waited to be added to the queue of pending
int Db { get; } /// redis commands. A large TimeSpan indicates serious contention for
/// the pending queue.
/// <summary> /// </summary>
/// The name of this command. TimeSpan CreationToEnqueued { get; }
/// </summary>
string Command { get; } /// <summary>
/// How long this command spent in the pending queue before being sent to redis.
/// <summary> /// A large TimeSpan can indicate a large number of pending events, large pending events,
/// The CommandFlags the command was submitted with. /// or network issues.
/// </summary> /// </summary>
CommandFlags Flags { get; } TimeSpan EnqueuedToSending { get; }
/// <summary> /// <summary>
/// When this command was *created*, will be approximately /// How long before Redis responded to this command and it's response could be handled after it was sent.
/// when the paired method of StackExchange.Redis was called but /// A large TimeSpan can indicate a large response body, an overtaxed redis instance, or network issues.
/// before that method returned. /// </summary>
/// TimeSpan SentToResponse { get; }
/// Note that the resolution of the returned DateTime is limited by DateTime.UtcNow.
/// </summary> /// <summary>
DateTime CommandCreated { get; } /// How long between Redis responding to this command and awaiting consumers being notified.
/// </summary>
/// <summary> TimeSpan ResponseToCompletion { get; }
/// How long this command waited to be added to the queue of pending
/// redis commands. A large TimeSpan indicates serious contention for /// <summary>
/// the pending queue. /// How long it took this redis command to be processed, from creation to deserializing the final response.
/// </summary> ///
TimeSpan CreationToEnqueued { get; } /// Note that this TimeSpan *does not* include time spent awaiting a Task in consumer code.
/// </summary>
/// <summary> TimeSpan ElapsedTime { get; }
/// How long this command spent in the pending queue before being sent to redis.
/// A large TimeSpan can indicate a large number of pending events, large pending events, /// <summary>
/// or network issues. /// If a command has to be resent due to an ASK or MOVED response from redis (in a cluster configuration),
/// </summary> /// the second sending of the command will have this property set to the original IProfiledCommand.
TimeSpan EnqueuedToSending { get; } ///
/// This can only be set if redis is configured as a cluster.
/// <summary> /// </summary>
/// How long before Redis responded to this command and it's response could be handled after it was sent. IProfiledCommand RetransmissionOf { get; }
/// A large TimeSpan can indicate a large response body, an overtaxed redis instance, or network issues.
/// </summary> /// <summary>
TimeSpan SentToResponse { get; } /// If RetransmissionOf is not null, this property will be set to either Ask or Moved to indicate
/// what sort of response triggered the retransmission.
/// <summary> ///
/// How long between Redis responding to this command and awaiting consumers being notified. /// This can be useful for determining the root cause of extra commands.
/// </summary> /// </summary>
TimeSpan ResponseToCompletion { get; } RetransmissionReasonType? RetransmissionReason { get; }
}
/// <summary>
/// How long it took this redis command to be processed, from creation to deserializing the final response. /// <summary>
/// /// Interface for profiling individual commands against an Redis ConnectionMulitplexer.
/// Note that this TimeSpan *does not* include time spent awaiting a Task in consumer code. /// </summary>
/// </summary> public interface IProfiler
TimeSpan ElapsedTime { get; } {
/// <summary>
/// <summary> /// Called to provide a context object.
/// If a command has to be resent due to an ASK or MOVED response from redis (in a cluster configuration), ///
/// the second sending of the command will have this property set to the original IProfiledCommand. /// This method is called before the method which triggers work against redis (such as StringSet(Async)) returns,
/// /// and will always be called on the same thread as that method.
/// This can only be set if redis is configured as a cluster. ///
/// </summary> /// Note that GetContext() may be called even if ConnectionMultiplexer.BeginProfiling() has not been called.
IProfiledCommand RetransmissionOf { get; } /// You may return `null` to prevent any tracking of commands.
/// </summary>
/// <summary> object GetContext();
/// 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; }
}
/// <summary>
/// Interface for profiling individual commands against an Redis ConnectionMulitplexer.
/// </summary>
public interface IProfiler
{
/// <summary>
/// Called to provide a context object.
///
/// This method is called before the method which triggers work against redis (such as StringSet(Async)) returns,
/// and will always be called on the same thread as that method.
///
/// Note that GetContext() may be called even if ConnectionMultiplexer.BeginProfiling() has not been called.
/// You may return `null` to prevent any tracking of commands.
/// </summary>
object GetContext();
}
}
...@@ -11,32 +11,12 @@ public partial interface IRedis : IRedisAsync ...@@ -11,32 +11,12 @@ public partial interface IRedis : IRedisAsync
/// <summary> /// <summary>
/// This command is often used to test if a connection is still alive, or to measure latency. /// This command is often used to test if a connection is still alive, or to measure latency.
/// </summary> /// </summary>
/// <param name="flags">The command flags to use when pinging.</param>
/// <returns>The observed latency.</returns> /// <returns>The observed latency.</returns>
/// <remarks>https://redis.io/commands/ping</remarks> /// <remarks>https://redis.io/commands/ping</remarks>
TimeSpan Ping(CommandFlags flags = CommandFlags.None); TimeSpan Ping(CommandFlags flags = CommandFlags.None);
} }
/// <summary>
/// Represents a resumable, cursor-based scanning operation
/// </summary>
public interface IScanningCursor
{
/// <summary>
/// Returns the cursor that represents the *active* page of results (not the pending/next page of results as returned by SCAN/HSCAN/ZSCAN/SSCAN)
/// </summary>
long Cursor { get; }
/// <summary>
/// The page size of the current operation
/// </summary>
int PageSize { get; }
/// <summary>
/// The offset into the current page
/// </summary>
int PageOffset { get; }
}
[Conditional("DEBUG")] [Conditional("DEBUG")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
internal class IgnoreNamePrefixAttribute : Attribute internal class IgnoreNamePrefixAttribute : Attribute
...@@ -46,6 +26,6 @@ public IgnoreNamePrefixAttribute(bool ignoreEntireMethod = false) ...@@ -46,6 +26,6 @@ public IgnoreNamePrefixAttribute(bool ignoreEntireMethod = false)
IgnoreEntireMethod = ignoreEntireMethod; IgnoreEntireMethod = ignoreEntireMethod;
} }
public bool IgnoreEntireMethod { get; private set; } public bool IgnoreEntireMethod { get; }
} }
} }
\ No newline at end of file
...@@ -19,6 +19,7 @@ public partial interface IRedisAsync ...@@ -19,6 +19,7 @@ public partial interface IRedisAsync
/// <returns>The observed latency.</returns> /// <returns>The observed latency.</returns>
/// <remarks>https://redis.io/commands/ping</remarks> /// <remarks>https://redis.io/commands/ping</remarks>
Task<TimeSpan> PingAsync(CommandFlags flags = CommandFlags.None); Task<TimeSpan> PingAsync(CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Wait for a given asynchronous operation to complete (or timeout), reporting which /// Wait for a given asynchronous operation to complete (or timeout), reporting which
/// </summary> /// </summary>
...@@ -28,14 +29,15 @@ public partial interface IRedisAsync ...@@ -28,14 +29,15 @@ public partial interface IRedisAsync
/// Wait for a given asynchronous operation to complete (or timeout) /// Wait for a given asynchronous operation to complete (or timeout)
/// </summary> /// </summary>
void Wait(Task task); void Wait(Task task);
/// <summary> /// <summary>
/// Wait for a given asynchronous operation to complete (or timeout) /// Wait for a given asynchronous operation to complete (or timeout)
/// </summary> /// </summary>
T Wait<T>(Task<T> task); T Wait<T>(Task<T> task);
/// <summary> /// <summary>
/// Wait for the given asynchronous operations to complete (or timeout) /// Wait for the given asynchronous operations to complete (or timeout)
/// </summary> /// </summary>
void WaitAll(params Task[] tasks); void WaitAll(params Task[] tasks);
} }
} }
namespace StackExchange.Redis
{
/// <summary>
/// Represents a resumable, cursor-based scanning operation
/// </summary>
public interface IScanningCursor
{
/// <summary>
/// Returns the cursor that represents the *active* page of results (not the pending/next page of results as returned by SCAN/HSCAN/ZSCAN/SSCAN)
/// </summary>
long Cursor { get; }
/// <summary>
/// The page size of the current operation
/// </summary>
int PageSize { get; }
/// <summary>
/// The offset into the current page
/// </summary>
int PageOffset { get; }
}
}
\ No newline at end of file
...@@ -51,7 +51,7 @@ public partial interface IServer : IRedis ...@@ -51,7 +51,7 @@ public partial interface IServer : IRedis
/// Gets the version of the connected server /// Gets the version of the connected server
/// </summary> /// </summary>
Version Version { get; } Version Version { get; }
/// <summary> /// <summary>
/// The CLIENT KILL command closes a given client connection identified by ip:port. /// The CLIENT KILL command closes a given client connection identified by ip:port.
/// The ip:port should match a line returned by the CLIENT LIST command. /// The ip:port should match a line returned by the CLIENT LIST command.
...@@ -74,6 +74,7 @@ public partial interface IServer : IRedis ...@@ -74,6 +74,7 @@ public partial interface IServer : IRedis
/// <returns>the number of clients killed.</returns> /// <returns>the number of clients killed.</returns>
/// <remarks>https://redis.io/commands/client-kill</remarks> /// <remarks>https://redis.io/commands/client-kill</remarks>
long ClientKill(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None); long ClientKill(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// The CLIENT KILL command closes multiple connections that match the specified filters /// The CLIENT KILL command closes multiple connections that match the specified filters
/// </summary> /// </summary>
...@@ -349,6 +350,7 @@ public partial interface IServer : IRedis ...@@ -349,6 +350,7 @@ public partial interface IServer : IRedis
/// </summary> /// </summary>
/// <remarks>https://redis.io/commands/slaveof</remarks> /// <remarks>https://redis.io/commands/slaveof</remarks>
void SlaveOf(EndPoint master, CommandFlags flags = CommandFlags.None); void SlaveOf(EndPoint master, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// The SLAVEOF command can change the replication settings of a slave on the fly. If a Redis server is already acting as slave, specifying a null master will turn off the replication, turning the Redis server into a MASTER. Specifying a non-null master will make the server a slave of another server listening at the specified hostname and port. /// The SLAVEOF command can change the replication settings of a slave on the fly. If a Redis server is already acting as slave, specifying a null master will turn off the replication, turning the Redis server into a MASTER. Specifying a non-null master will make the server a slave of another server listening at the specified hostname and port.
/// </summary> /// </summary>
...@@ -360,21 +362,25 @@ public partial interface IServer : IRedis ...@@ -360,21 +362,25 @@ public partial interface IServer : IRedis
/// </summary> /// </summary>
/// <remarks>https://redis.io/commands/slowlog</remarks> /// <remarks>https://redis.io/commands/slowlog</remarks>
CommandTrace[] SlowlogGet(int count = 0, CommandFlags flags = CommandFlags.None); CommandTrace[] SlowlogGet(int count = 0, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// To read the slow log the SLOWLOG GET command is used, that returns every entry in the slow log. It is possible to return only the N most recent entries passing an additional argument to the command (for instance SLOWLOG GET 10). /// To read the slow log the SLOWLOG GET command is used, that returns every entry in the slow log. It is possible to return only the N most recent entries passing an additional argument to the command (for instance SLOWLOG GET 10).
/// </summary> /// </summary>
/// <remarks>https://redis.io/commands/slowlog</remarks> /// <remarks>https://redis.io/commands/slowlog</remarks>
Task<CommandTrace[]> SlowlogGetAsync(int count = 0, CommandFlags flags = CommandFlags.None); Task<CommandTrace[]> SlowlogGetAsync(int count = 0, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever. /// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever.
/// </summary> /// </summary>
/// <remarks>https://redis.io/commands/slowlog</remarks> /// <remarks>https://redis.io/commands/slowlog</remarks>
void SlowlogReset(CommandFlags flags = CommandFlags.None); void SlowlogReset(CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever. /// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever.
/// </summary> /// </summary>
/// <remarks>https://redis.io/commands/slowlog</remarks> /// <remarks>https://redis.io/commands/slowlog</remarks>
Task SlowlogResetAsync(CommandFlags flags = CommandFlags.None); Task SlowlogResetAsync(CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Lists the currently active channels. An active channel is a Pub/Sub channel with one ore more subscribers (not including clients subscribed to patterns). /// Lists the currently active channels. An active channel is a Pub/Sub channel with one ore more subscribers (not including clients subscribed to patterns).
/// </summary> /// </summary>
...@@ -421,6 +427,7 @@ public partial interface IServer : IRedis ...@@ -421,6 +427,7 @@ public partial interface IServer : IRedis
/// <returns>The server's current time.</returns> /// <returns>The server's current time.</returns>
/// <remarks>https://redis.io/commands/time</remarks> /// <remarks>https://redis.io/commands/time</remarks>
DateTime Time(CommandFlags flags = CommandFlags.None); DateTime Time(CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// The TIME command returns the current server time. /// The TIME command returns the current server time.
/// </summary> /// </summary>
...@@ -523,7 +530,4 @@ public partial interface IServer : IRedis ...@@ -523,7 +530,4 @@ public partial interface IServer : IRedis
#endregion #endregion
} }
} }
\ No newline at end of file
...@@ -9,7 +9,6 @@ namespace StackExchange.Redis ...@@ -9,7 +9,6 @@ namespace StackExchange.Redis
/// </summary> /// </summary>
public interface ISubscriber : IRedis public interface ISubscriber : IRedis
{ {
/// <summary> /// <summary>
/// Inidicate exactly which redis server we are talking to /// Inidicate exactly which redis server we are talking to
/// </summary> /// </summary>
...@@ -36,12 +35,14 @@ public interface ISubscriber : IRedis ...@@ -36,12 +35,14 @@ public interface ISubscriber : IRedis
/// <returns>the number of clients that received the message.</returns> /// <returns>the number of clients that received the message.</returns>
/// <remarks>https://redis.io/commands/publish</remarks> /// <remarks>https://redis.io/commands/publish</remarks>
long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Posts a message to the given channel. /// Posts a message to the given channel.
/// </summary> /// </summary>
/// <returns>the number of clients that received the message.</returns> /// <returns>the number of clients that received the message.</returns>
/// <remarks>https://redis.io/commands/publish</remarks> /// <remarks>https://redis.io/commands/publish</remarks>
Task<long> PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); Task<long> PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Subscribe to perform some operation when a change to the preferred/active node is broadcast. /// Subscribe to perform some operation when a change to the preferred/active node is broadcast.
/// </summary> /// </summary>
......
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