Commit ad868210 authored by kevin-montrose's avatar kevin-montrose

squash named-script-parameters branch into a single commit

parent dcf546f4
......@@ -16,3 +16,4 @@ Mono/
redis-cli.exe
Redis Configs/*.dat
RedisQFork*.dat
StackExchange.Redis.*.zip
\ No newline at end of file
This diff is collapsed.
......@@ -74,6 +74,7 @@
<Compile Include="StackExchange\Redis\HashEntry.cs" />
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="StackExchange\Redis\LuaScript.cs" />
<Compile Include="StackExchange\Redis\RedisChannel.cs" />
<Compile Include="StackExchange\Redis\Bitwise.cs" />
<Compile Include="StackExchange\Redis\ClientFlags.cs" />
......@@ -139,6 +140,7 @@
<Compile Include="StackExchange\Redis\ResultProcessor.cs" />
<Compile Include="StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="StackExchange\Redis\ResultType.cs" />
<Compile Include="StackExchange\Redis\ScriptParameterMapper.cs" />
<Compile Include="StackExchange\Redis\ServerCounters.cs" />
<Compile Include="StackExchange\Redis\ServerEndPoint.cs" />
<Compile Include="StackExchange\Redis\ServerSelectionStrategy.cs" />
......
......@@ -68,6 +68,7 @@
<Compile Include="StackExchange\Redis\HashEntry.cs" />
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="StackExchange\Redis\LuaScript.cs" />
<Compile Include="StackExchange\Redis\RedisChannel.cs" />
<Compile Include="StackExchange\Redis\Bitwise.cs" />
<Compile Include="StackExchange\Redis\ClientFlags.cs" />
......@@ -133,6 +134,7 @@
<Compile Include="StackExchange\Redis\ResultProcessor.cs" />
<Compile Include="StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="StackExchange\Redis\ResultType.cs" />
<Compile Include="StackExchange\Redis\ScriptParameterMapper.cs" />
<Compile Include="StackExchange\Redis\ServerCounters.cs" />
<Compile Include="StackExchange\Redis\ServerEndPoint.cs" />
<Compile Include="StackExchange\Redis\ServerSelectionStrategy.cs" />
......
......@@ -51,6 +51,30 @@ public static ConfiguredTaskAwaitable<T> ForAwait<T>(this Task<T> task)
/// </summary>
public sealed partial class ConnectionMultiplexer : IDisposable
{
private static TaskFactory _factory = null;
/// <summary>
/// Provides a way of overriding the default Task Factory. If not set, it will use the default Task.Factory.
/// Useful when top level code sets it's own factory which may interfere with Redis queries.
/// </summary>
public static TaskFactory Factory
{
get
{
if (_factory != null)
{
return _factory;
}
return Task.Factory;
}
set
{
_factory = value;
}
}
/// <summary>
/// Get summary statistics associates with this server
/// </summary>
......@@ -738,7 +762,7 @@ private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> mul
killMe = muxer;
// note that task has timeouts internally, so it might take *just over* the regular timeout
// wrap into task to force async execution
var task = Task.Factory.StartNew(() => { return muxer.ReconfigureAsync(true, false, log, null, "connect").Result; });
var task = Factory.StartNew(() => { return muxer.ReconfigureAsync(true, false, log, null, "connect").Result; });
if (!task.Wait(muxer.SyncConnectTimeout(true)))
{
......@@ -1472,9 +1496,38 @@ private ServerEndPoint SelectServerByElection(ServerEndPoint[] servers, string e
return servers[i];
}
LogLocked(log, "...but we couldn't find that");
var deDottedEndpoint = DeDotifyHost(endpoint);
for (int i = 0; i < servers.Length; i++)
{
if (string.Equals(DeDotifyHost(Format.ToString(servers[i].EndPoint)), deDottedEndpoint, StringComparison.OrdinalIgnoreCase))
{
LogLocked(log, "...but we did find instead: {0}", deDottedEndpoint);
return servers[i];
}
}
return null;
}
static string DeDotifyHost(string input)
{
if (string.IsNullOrWhiteSpace(input)) return input; // GIGO
if (!char.IsLetter(input[0])) return input; // need first char to be alpha for this to work
int periodPosition = input.IndexOf('.');
if (periodPosition <= 0) return input; // no period or starts with a period? nothing useful to split
int colonPosition = input.IndexOf(':');
if (colonPosition > 0)
{ // has a port specifier
return input.Substring(0, periodPosition) + input.Substring(colonPosition);
}
else
{
return input.Substring(0, periodPosition);
}
}
internal void UpdateClusterRange(ClusterConfiguration configuration)
{
if (configuration == null) return;
......@@ -1852,5 +1905,4 @@ public Task<long> PublishReconfigureAsync(CommandFlags flags = CommandFlags.None
return GetSubscriber().PublishAsync(channel, RedisLiterals.Wildcard, flags);
}
}
}
......@@ -452,6 +452,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// <returns>the number of clients that received the message.</returns>
/// <remarks>http://redis.io/commands/publish</remarks>
long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Execute a Lua script against the server
/// </summary>
......@@ -466,6 +467,19 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// <returns>A dynamic representation of the script's result</returns>
RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Execute a lua script against the server, using previously prepared script.
/// Named parameters, if any, are provided by the `parameters` object.
/// </summary>
RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Execute a lua script against the server, using previously prepared and loaded script.
/// This method sends only the SHA1 hash of the lua script to Redis.
/// Named parameters, if any, are provided by the `parameters` object.
/// </summary>
RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members.
/// </summary>
......
......@@ -439,6 +439,19 @@ public interface IDatabaseAsync : IRedisAsync
/// <returns>A dynamic representation of the script's result</returns>
Task<RedisResult> ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Execute a lua script against the server, using previously prepared script.
/// Named parameters, if any, are provided by the `parameters` object.
/// </summary>
Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Execute a lua script against the server, using previously prepared and loaded script.
/// This method sends only the SHA1 hash of the lua script to Redis.
/// Named parameters, if any, are provided by the `parameters` object.
/// </summary>
Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members.
/// </summary>
......
......@@ -314,11 +314,21 @@ public partial interface IServer : IRedis
/// </summary>
byte[] ScriptLoad(string script, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Explicitly defines a script on the server
/// </summary>
LoadedLuaScript ScriptLoad(LuaScript script, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Explicitly defines a script on the server
/// </summary>
Task<byte[]> ScriptLoadAsync(string script, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Explicitly defines a script on the server
/// </summary>
Task<LoadedLuaScript> ScriptLoadAsync(LuaScript script, CommandFlags flags = CommandFlags.None);
/// <summary>Asks the redis server to shutdown, killing all connections. Please FULLY read the notes on the SHUTDOWN command.</summary>
/// <remarks>http://redis.io/commands/shutdown</remarks>
void Shutdown(ShutdownMode shutdownMode = ShutdownMode.Default, CommandFlags flags = CommandFlags.None);
......
......@@ -323,6 +323,18 @@ public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisVa
return this.Inner.ScriptEvaluate(script, this.ToInner(keys), values, flags);
}
public RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
// TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those?
return script.Evaluate(this.Inner, parameters, Prefix, flags);
}
public RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
// TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those?
return script.Evaluate(this.Inner, parameters, Prefix, flags);
}
public long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
{
return this.Inner.SetAdd(this.ToInner(key), values, flags);
......
......@@ -334,6 +334,16 @@ public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = nu
return this.Inner.ScriptEvaluateAsync(script, this.ToInner(keys), values, flags);
}
public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
throw new NotImplementedException();
}
public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
throw new NotImplementedException();
}
public Task<long> SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
{
return this.Inner.SetAddAsync(this.ToInner(key), values, flags);
......
This diff is collapsed.
......@@ -375,6 +375,16 @@ public Task<byte[]> ScriptLoadAsync(string script, CommandFlags flags = CommandF
return ExecuteAsync(msg, ResultProcessor.ScriptLoad);
}
public LoadedLuaScript ScriptLoad(LuaScript script, CommandFlags flags = CommandFlags.None)
{
return script.Load(this, flags);
}
public Task<LoadedLuaScript> ScriptLoadAsync(LuaScript script, CommandFlags flags = CommandFlags.None)
{
return script.LoadAsync(this, flags);
}
public void Shutdown(ShutdownMode shutdownMode = ShutdownMode.Default, CommandFlags flags = CommandFlags.None)
{
Message msg;
......@@ -563,12 +573,35 @@ internal override RedisFeatures GetFeatures(int db, RedisKey key, CommandFlags f
public void SlaveOf(EndPoint endpoint, CommandFlags flags = CommandFlags.None)
{
var msg = CreateSlaveOfMessage(endpoint, flags);
if (endpoint == server.EndPoint)
{
throw new ArgumentException("Cannot slave to self");
}
ExecuteSync(msg, ResultProcessor.DemandOK);
// prepare the actual slaveof message (not sent yet)
var slaveofMsg = CreateSlaveOfMessage(endpoint, flags);
var configuration = this.multiplexer.RawConfig;
// attempt to cease having an opinion on the master; will resume that when replication completes
// (note that this may fail; we aren't depending on it)
if (!string.IsNullOrWhiteSpace(configuration.TieBreaker)
&& this.multiplexer.CommandMap.IsAvailable(RedisCommand.DEL))
{
var del = Message.Create(0, CommandFlags.FireAndForget | CommandFlags.NoRedirect, RedisCommand.DEL, (RedisKey)configuration.TieBreaker);
del.SetInternalCall();
server.QueueDirectFireAndForget(del, ResultProcessor.Boolean);
}
ExecuteSync(slaveofMsg, ResultProcessor.DemandOK);
// attempt to broadcast a reconfigure message to anybody listening to this server
var channel = this.multiplexer.ConfigurationChangedChannel;
if (channel != null && this.multiplexer.CommandMap.IsAvailable(RedisCommand.PUBLISH))
{
var pub = Message.Create(-1, CommandFlags.FireAndForget | CommandFlags.NoRedirect, RedisCommand.PUBLISH, (RedisValue)channel, RedisLiterals.Wildcard);
pub.SetInternalCall();
server.QueueDirectFireAndForget(pub, ResultProcessor.Int64);
}
}
public Task SlaveOfAsync(EndPoint endpoint, CommandFlags flags = CommandFlags.None)
......
......@@ -113,6 +113,7 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MessageCompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MessageQueue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LuaScript.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Order.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\PhysicalBridge.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\PhysicalConnection.cs" />
......@@ -136,6 +137,7 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultBox.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultProcessor.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ScriptParameterMapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SaveType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerEndPoint.cs" />
......
......@@ -107,6 +107,7 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MessageCompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MessageQueue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LuaScript.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Order.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\PhysicalBridge.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\PhysicalConnection.cs" />
......@@ -130,6 +131,7 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultBox.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultProcessor.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ResultType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ScriptParameterMapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SaveType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerEndPoint.cs" />
......
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