Commit af605dd6 authored by Marc Gravell's avatar Marc Gravell

Merge branch 'jeremymeng-netcore' of...

Merge branch 'jeremymeng-netcore' of github.com:StackExchange/StackExchange.Redis into jeremymeng-netcore
parents 2712ccf9 42593761
.hg .hg
bin bin
bin.snk bin.snk
obj obj
*.suo *.suo
*.user *.user
*.nupkg *.nupkg
packages/NuGet.CommandLine.* packages/NuGet.CommandLine.*
*.sln.docstates *.sln.docstates
_ReSharper.* _ReSharper.*
Mono/ Mono/
*.sln.ide *.sln.ide
*.rdb *.rdb
*.aof *.aof
*.orig *.orig
redis-cli.exe redis-cli.exe
Redis Configs/*.dat Redis Configs/*.dat
RedisQFork*.dat RedisQFork*.dat
StackExchange.Redis.*.zip StackExchange.Redis.*.zip
.vs/ .vs/
*.lock.json *.lock.json
\ No newline at end of file
...@@ -48,13 +48,13 @@ ...@@ -48,13 +48,13 @@
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\StackExchange.Redis\StackExchange.Redis.csproj"> <Folder Include="Properties\" />
<Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project>
<Name>StackExchange.Redis</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <ProjectReference Include="..\StackExchange.Redis_Net45\StackExchange.Redis_Net45.csproj">
<Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project>
<Name>StackExchange.Redis_Net45</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
......
{ {
"version": "1.0.0-*", "version": "1.0.0-*",
"description": "StackExchange.Redis.BasicTest dnxcore50", "description": "StackExchange.Redis.BasicTest dnxcore50",
"authors": [ "jeremymeng" ], "authors": [ "" ],
"tags": [ "" ], "tags": [ "" ],
"projectUrl": "", "projectUrl": "",
"licenseUrl": "", "licenseUrl": "",
...@@ -9,11 +9,12 @@ ...@@ -9,11 +9,12 @@
"compile": [ "compile": [
"../BasicTest/Program.cs" "../BasicTest/Program.cs"
], ],
"dependencies": { "dependencies": {
"StackExchange.Redis": "1.1.0-*" "StackExchange.Redis": {
"version": "1.1.0-alpha1",
"target": "project"
}
}, },
"commands": { "commands": {
"run": "BasicTest_dnxcore50" "run": "BasicTest_dnxcore50"
}, },
...@@ -34,7 +35,7 @@ ...@@ -34,7 +35,7 @@
"frameworks": { "frameworks": {
"dnxcore50": { "dnxcore50": {
"dependencies": { "dependencies": {
"System.Console": "4.0.0-beta-23409" "System.Console": "4.0.0-beta-23516"
} }
} }
} }
......
...@@ -113,9 +113,9 @@ ...@@ -113,9 +113,9 @@
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\StackExchange.Redis\StackExchange.Redis.csproj"> <ProjectReference Include="..\StackExchange.Redis_Net45\StackExchange.Redis_Net45.csproj">
<Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project> <Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project>
<Name>StackExchange.Redis</Name> <Name>StackExchange.Redis_Net45</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
......
...@@ -87,13 +87,13 @@ ...@@ -87,13 +87,13 @@
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\StackExchange.Redis\StackExchange.Redis.csproj"> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
<Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project>
<Name>StackExchange.Redis</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> <ProjectReference Include="..\StackExchange.Redis_Net45\StackExchange.Redis_Net45.csproj">
<Project>{7cec07f2-8c03-4c42-b048-738b215824c1}</Project>
<Name>StackExchange.Redis_Net45</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
......
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>46754d2a-ac16-4686-b113-3db08acf4269</ProjectGuid>
<RootNamespace>StackExchange.Redis.StrongName</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
\ No newline at end of file
{
"version": "1.1.0-alpha1",
"description": "High performance Redis client, incorporating both synchronous and asynchronous usage.",
"authors": [ "Stack Exchange inc., marc.gravell" ],
"owners": [ "marc.gravell" ],
"tags": [ "Async", "Redis", "Cache", "PubSub", "Messaging" ],
"projectUrl": "https://github.com/StackExchange/StackExchange.Redis",
"licenseUrl": "https://raw.github.com/StackExchange/StackExchange.Redis/master/LICENSE",
"copyright": "Stack Exchange inc. 2014-",
"requireLicenseAcceptance": false,
"summary": "Redis client library",
"compile": [
"../StackExchange.Redis/**/*.cs"
],
"dependencies": {
},
"compilationOptions": {
"allowUnsafe": true,
"keyFile": "../StackExchange.Redis.snk",
"define": [ "STRONG_NAME" ]
},
"frameworks": {
"net40": {
"dependencies": {
"Microsoft.Bcl": "1.1.10",
"Microsoft.Bcl.Async": "1.0.168"
},
"compilationOptions": {
"define": [ "FEATURE_SERIALIZATION" ]
}
},
"net45": {
"frameworkAssemblies": {
"System.IO.Compression": "4.0.0.0"
},
"compilationOptions": {
"define": [ "FEATURE_SERIALIZATION" ]
}
},
"net46": {
"frameworkAssemblies": {
"System.IO.Compression": "4.0.0.0"
},
"define": [ "FEATURE_SERIALIZATION", "PLAT_SAFE_CONTINUATIONS" ]
},
"dnxcore50": {
"compilationOptions": {
"define": [ "PLAT_SAFE_CONTINUATIONS", "CORE_CLR" ]
},
"dependencies": {
"System.Collections.Concurrent": "4.0.11-beta-23516",
"System.Collections.NonGeneric": "4.0.1-beta-23516",
"System.Diagnostics.Debug": "4.0.11-beta-23516",
"System.Diagnostics.Tools": "4.0.1-beta-23516",
"System.Diagnostics.TraceSource": "4.0.0-beta-23516",
"System.Globalization": "4.0.11-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.IO.Compression": "4.1.0-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Net.NameResolution": "4.0.0-beta-23516",
"System.Net.Primitives": "4.0.11-beta-23516",
"System.Net.Security": "4.0.0-beta-23516",
"System.Net.Sockets": "4.1.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Reflection.Emit": "4.0.1-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.Reflection.Primitives": "4.0.1-beta-23516",
"System.Reflection.TypeExtensions": "4.1.0-beta-23516",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
"System.Security.Cryptography.X509Certificates": "4.0.0-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516",
"System.Threading.Thread": "4.0.0-beta-23516",
"System.Threading.ThreadPool": "4.0.10-beta-23516",
"System.Threading.Timer": "4.0.1-beta-23516"
}
},
"dotnet5.5": {
"compilationOptions": {
"define": [ "PLAT_SAFE_CONTINUATIONS", "CORE_CLR" ]
},
"dependencies": {
"System.Collections.Concurrent": "4.0.11-beta-23516",
"System.Collections.NonGeneric": "4.0.1-beta-23516",
"System.Diagnostics.Debug": "4.0.11-beta-23516",
"System.Diagnostics.Tools": "4.0.1-beta-23516",
"System.Diagnostics.TraceSource": "4.0.0-beta-23516",
"System.Globalization": "4.0.11-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.IO.Compression": "4.1.0-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Net.NameResolution": "4.0.0-beta-23516",
"System.Net.Primitives": "4.0.11-beta-23516",
"System.Net.Security": "4.0.0-beta-23516",
"System.Net.Sockets": "4.1.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Reflection.Emit": "4.0.1-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.Reflection.Primitives": "4.0.1-beta-23516",
"System.Reflection.TypeExtensions": "4.1.0-beta-23516",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
"System.Security.Cryptography.X509Certificates": "4.0.0-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516",
"System.Threading.Thread": "4.0.0-beta-23516",
"System.Threading.ThreadPool": "4.0.10-beta-23516",
"System.Threading.Timer": "4.0.1-beta-23516"
}
}
}
}
\ No newline at end of file
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
#if FEATURE_BOOKSLEEVE #if FEATURE_BOOKSLEEVE
using BookSleeve; using BookSleeve;
#endif #endif
using NUnit.Framework; using NUnit.Framework;
using StackExchange.Redis.KeyspaceIsolation; using StackExchange.Redis.KeyspaceIsolation;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
{ {
[TestFixture] [TestFixture]
public class BasicOpsTests : TestBase public class BasicOpsTests : TestBase
{ {
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void PingOnce(bool preserveOrder) public void PingOnce(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
var task = conn.PingAsync(); var task = conn.PingAsync();
var duration = muxer.Wait(task); var duration = muxer.Wait(task);
Console.WriteLine("Ping took: " + duration); Console.WriteLine("Ping took: " + duration);
Assert.IsTrue(duration.TotalMilliseconds > 0); Assert.IsTrue(duration.TotalMilliseconds > 0);
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void RapidDispose(bool preserverOrder) public void RapidDispose(bool preserverOrder)
{ {
RedisKey key = Me(); RedisKey key = Me();
using (var primary = Create()) using (var primary = Create())
{ {
var conn = primary.GetDatabase(); var conn = primary.GetDatabase();
conn.KeyDelete(key); conn.KeyDelete(key);
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
using (var secondary = Create(fail: true)) using (var secondary = Create(fail: true))
{ {
secondary.GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget); secondary.GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget);
} }
} }
Assert.AreEqual(10, (int)conn.StringGet(key)); Assert.AreEqual(10, (int)conn.StringGet(key));
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void PingMany(bool preserveOrder) public void PingMany(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
var tasks = new Task<TimeSpan>[10000]; var tasks = new Task<TimeSpan>[10000];
for (int i = 0; i < tasks.Length; i++) for (int i = 0; i < tasks.Length; i++)
{ {
tasks[i] = conn.PingAsync(); tasks[i] = conn.PingAsync();
} }
muxer.WaitAll(tasks); muxer.WaitAll(tasks);
Assert.IsTrue(tasks[0].Result.TotalMilliseconds > 0); Assert.IsTrue(tasks[0].Result.TotalMilliseconds > 0);
Assert.IsTrue(tasks[tasks.Length - 1].Result.TotalMilliseconds > 0); Assert.IsTrue(tasks[tasks.Length - 1].Result.TotalMilliseconds > 0);
} }
} }
[Test] [Test]
public void GetWithNullKey() public void GetWithNullKey()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = null; string key = null;
Assert.Throws<ArgumentException>( Assert.Throws<ArgumentException>(
() => db.StringGet(key), () => db.StringGet(key),
"A null key is not valid in this context"); "A null key is not valid in this context");
} }
} }
[Test] [Test]
public void SetWithNullKey() public void SetWithNullKey()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = null, value = "abc"; string key = null, value = "abc";
Assert.Throws<ArgumentException>( Assert.Throws<ArgumentException>(
() => db.StringSet(key, value), () => db.StringSet(key, value),
"A null key is not valid in this context"); "A null key is not valid in this context");
} }
} }
[Test] [Test]
public void SetWithNullValue() public void SetWithNullValue()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = Me(), value = null; string key = Me(), value = null;
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); db.StringSet(key, "abc", flags: CommandFlags.FireAndForget);
Assert.IsTrue(db.KeyExists(key)); Assert.IsTrue(db.KeyExists(key));
db.StringSet(key, value); db.StringSet(key, value);
var actual = (string)db.StringGet(key); var actual = (string)db.StringGet(key);
Assert.IsNull(actual); Assert.IsNull(actual);
Assert.IsFalse(db.KeyExists(key)); Assert.IsFalse(db.KeyExists(key));
} }
} }
[Test] [Test]
public void SetWithDefaultValue() public void SetWithDefaultValue()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = Me(); string key = Me();
var value = default(RedisValue); // this is kinda 0... ish var value = default(RedisValue); // this is kinda 0... ish
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); db.StringSet(key, "abc", flags: CommandFlags.FireAndForget);
Assert.IsTrue(db.KeyExists(key)); Assert.IsTrue(db.KeyExists(key));
db.StringSet(key, value); db.StringSet(key, value);
var actual = (string)db.StringGet(key); var actual = (string)db.StringGet(key);
Assert.IsNull(actual); Assert.IsNull(actual);
Assert.IsFalse(db.KeyExists(key)); Assert.IsFalse(db.KeyExists(key));
} }
} }
[Test] [Test]
public void SetWithZeroValue() public void SetWithZeroValue()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = Me(); string key = Me();
long value = 0; long value = 0;
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); db.StringSet(key, "abc", flags: CommandFlags.FireAndForget);
Assert.IsTrue(db.KeyExists(key)); Assert.IsTrue(db.KeyExists(key));
db.StringSet(key, value); db.StringSet(key, value);
var actual = (string)db.StringGet(key); var actual = (string)db.StringGet(key);
Assert.AreEqual("0", actual); Assert.AreEqual("0", actual);
Assert.IsTrue(db.KeyExists(key)); Assert.IsTrue(db.KeyExists(key));
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void GetSetAsync(bool preserveOrder) public void GetSetAsync(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
var d0 = conn.KeyDeleteAsync(key); var d0 = conn.KeyDeleteAsync(key);
var d1 = conn.KeyDeleteAsync(key); var d1 = conn.KeyDeleteAsync(key);
var g1 = conn.StringGetAsync(key); var g1 = conn.StringGetAsync(key);
var s1 = conn.StringSetAsync(key, "123"); var s1 = conn.StringSetAsync(key, "123");
var g2 = conn.StringGetAsync(key); var g2 = conn.StringGetAsync(key);
var d2 = conn.KeyDeleteAsync(key); var d2 = conn.KeyDeleteAsync(key);
muxer.Wait(d0); muxer.Wait(d0);
Assert.IsFalse(muxer.Wait(d1)); Assert.IsFalse(muxer.Wait(d1));
Assert.IsNull((string)muxer.Wait(g1)); Assert.IsNull((string)muxer.Wait(g1));
Assert.IsTrue(muxer.Wait(g1).IsNull); Assert.IsTrue(muxer.Wait(g1).IsNull);
muxer.Wait(s1); muxer.Wait(s1);
Assert.AreEqual("123", (string)muxer.Wait(g2)); Assert.AreEqual("123", (string)muxer.Wait(g2));
Assert.AreEqual(123, (int)muxer.Wait(g2)); Assert.AreEqual(123, (int)muxer.Wait(g2));
Assert.IsFalse(muxer.Wait(g2).IsNull); Assert.IsFalse(muxer.Wait(g2).IsNull);
Assert.IsTrue(muxer.Wait(d2)); Assert.IsTrue(muxer.Wait(d2));
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void GetSetSync(bool preserveOrder) public void GetSetSync(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
conn.KeyDelete(key); conn.KeyDelete(key);
var d1 = conn.KeyDelete(key); var d1 = conn.KeyDelete(key);
var g1 = conn.StringGet(key); var g1 = conn.StringGet(key);
conn.StringSet(key, "123"); conn.StringSet(key, "123");
var g2 = conn.StringGet(key); var g2 = conn.StringGet(key);
var d2 = conn.KeyDelete(key); var d2 = conn.KeyDelete(key);
Assert.IsFalse(d1); Assert.IsFalse(d1);
Assert.IsNull((string)g1); Assert.IsNull((string)g1);
Assert.IsTrue(g1.IsNull); Assert.IsTrue(g1.IsNull);
Assert.AreEqual("123", (string)g2); Assert.AreEqual("123", (string)g2);
Assert.AreEqual(123, (int)g2); Assert.AreEqual(123, (int)g2);
Assert.IsFalse(g2.IsNull); Assert.IsFalse(g2.IsNull);
Assert.IsTrue(d2); Assert.IsTrue(d2);
} }
} }
[Test] [Test]
[TestCase(true, true)] [TestCase(true, true)]
[TestCase(true, false)] [TestCase(true, false)]
[TestCase(false, true)] [TestCase(false, true)]
[TestCase(false, false)] [TestCase(false, false)]
public void MassiveBulkOpsAsync(bool preserveOrder, bool withContinuation) public void MassiveBulkOpsAsync(bool preserveOrder, bool withContinuation)
{ {
#if DEBUG #if DEBUG
var oldAsyncCompletionCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); var oldAsyncCompletionCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount();
#endif #endif
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
RedisKey key = "MBOA"; RedisKey key = "MBOA";
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
muxer.Wait(conn.PingAsync()); muxer.Wait(conn.PingAsync());
#if DNXCORE50 #if CORE_CLR
int number = 0; int number = 0;
#endif #endif
Action<Task> nonTrivial = delegate Action<Task> nonTrivial = delegate
{ {
#if !DNXCORE50 #if !CORE_CLR
Thread.SpinWait(5); Thread.SpinWait(5);
#else #else
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
number++; number++;
} }
#endif #endif
}; };
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
for (int i = 0; i <= AsyncOpsQty; i++) for (int i = 0; i <= AsyncOpsQty; i++)
{ {
var t = conn.StringSetAsync(key, i); var t = conn.StringSetAsync(key, i);
if (withContinuation) t.ContinueWith(nonTrivial); if (withContinuation) t.ContinueWith(nonTrivial);
} }
int val = (int)muxer.Wait(conn.StringGetAsync(key)); int val = (int)muxer.Wait(conn.StringGetAsync(key));
Assert.AreEqual(AsyncOpsQty, val); Assert.AreEqual(AsyncOpsQty, val);
watch.Stop(); watch.Stop();
Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}); ops/s: {5}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(), Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}); ops/s: {5}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(),
withContinuation ? "with continuation" : "no continuation", preserveOrder ? "preserve order" : "any order", withContinuation ? "with continuation" : "no continuation", preserveOrder ? "preserve order" : "any order",
AsyncOpsQty / watch.Elapsed.TotalSeconds); AsyncOpsQty / watch.Elapsed.TotalSeconds);
#if DEBUG #if DEBUG
Console.WriteLine("Async completion workers: " + (ConnectionMultiplexer.GetAsyncCompletionWorkerCount() - oldAsyncCompletionCount)); Console.WriteLine("Async completion workers: " + (ConnectionMultiplexer.GetAsyncCompletionWorkerCount() - oldAsyncCompletionCount));
#endif #endif
} }
} }
[Test] [Test]
[TestCase(false, false)] [TestCase(false, false)]
[TestCase(true, true)] [TestCase(true, true)]
[TestCase(true, false)] [TestCase(true, false)]
public void GetWithExpiry(bool exists, bool hasExpiry) public void GetWithExpiry(bool exists, bool hasExpiry)
{ {
using(var conn = Create()) using(var conn = Create())
{ {
var db = conn.GetDatabase(); var db = conn.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
db.KeyDelete(key); db.KeyDelete(key);
if (exists) if (exists)
{ {
if (hasExpiry) if (hasExpiry)
db.StringSet(key, "val", TimeSpan.FromMinutes(5)); db.StringSet(key, "val", TimeSpan.FromMinutes(5));
else else
db.StringSet(key, "val"); db.StringSet(key, "val");
} }
var async = db.StringGetWithExpiryAsync(key); var async = db.StringGetWithExpiryAsync(key);
var syncResult = db.StringGetWithExpiry(key); var syncResult = db.StringGetWithExpiry(key);
var asyncResult = db.Wait(async); var asyncResult = db.Wait(async);
if(exists) if(exists)
{ {
Assert.AreEqual("val", (string)asyncResult.Value); Assert.AreEqual("val", (string)asyncResult.Value);
Assert.AreEqual(hasExpiry, asyncResult.Expiry.HasValue); Assert.AreEqual(hasExpiry, asyncResult.Expiry.HasValue);
if (hasExpiry) Assert.IsTrue(asyncResult.Expiry.Value.TotalMinutes >= 4.9 && asyncResult.Expiry.Value.TotalMinutes <= 5); if (hasExpiry) Assert.IsTrue(asyncResult.Expiry.Value.TotalMinutes >= 4.9 && asyncResult.Expiry.Value.TotalMinutes <= 5);
Assert.AreEqual("val", (string)syncResult.Value); Assert.AreEqual("val", (string)syncResult.Value);
Assert.AreEqual(hasExpiry, syncResult.Expiry.HasValue); Assert.AreEqual(hasExpiry, syncResult.Expiry.HasValue);
if (hasExpiry) Assert.IsTrue(syncResult.Expiry.Value.TotalMinutes >= 4.9 && syncResult.Expiry.Value.TotalMinutes <= 5); if (hasExpiry) Assert.IsTrue(syncResult.Expiry.Value.TotalMinutes >= 4.9 && syncResult.Expiry.Value.TotalMinutes <= 5);
} }
else else
{ {
Assert.IsTrue(asyncResult.Value.IsNull); Assert.IsTrue(asyncResult.Value.IsNull);
Assert.IsFalse(asyncResult.Expiry.HasValue); Assert.IsFalse(asyncResult.Expiry.HasValue);
Assert.IsTrue(syncResult.Value.IsNull); Assert.IsTrue(syncResult.Value.IsNull);
Assert.IsFalse(syncResult.Expiry.HasValue); Assert.IsFalse(syncResult.Expiry.HasValue);
} }
} }
} }
[Test] [Test]
public void GetWithExpiryWrongTypeAsync() public void GetWithExpiryWrongTypeAsync()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var db = conn.GetDatabase(); var db = conn.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
db.KeyDelete(key); db.KeyDelete(key);
db.SetAdd(key, "abc"); db.SetAdd(key, "abc");
Assert.Throws<RedisServerException>(() => Assert.Throws<RedisServerException>(() =>
{ {
try try
{ {
var async = db.Wait(db.StringGetWithExpiryAsync(key)); var async = db.Wait(db.StringGetWithExpiryAsync(key));
} }
catch (AggregateException ex) catch (AggregateException ex)
{ {
throw ex.InnerExceptions[0]; throw ex.InnerExceptions[0];
} }
Assert.Fail(); Assert.Fail();
}, },
"A null key is not valid in this context"); "A null key is not valid in this context");
} }
} }
[Test] [Test]
public void GetWithExpiryWrongTypeSync() public void GetWithExpiryWrongTypeSync()
{ {
Assert.Throws<RedisServerException>(() => Assert.Throws<RedisServerException>(() =>
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var db = conn.GetDatabase(); var db = conn.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
db.KeyDelete(key); db.KeyDelete(key);
db.SetAdd(key, "abc"); db.SetAdd(key, "abc");
db.StringGetWithExpiry(key); db.StringGetWithExpiry(key);
Assert.Fail(); Assert.Fail();
} }
}, },
"WRONGTYPE Operation against a key holding the wrong kind of value"); "WRONGTYPE Operation against a key holding the wrong kind of value");
} }
#if FEATURE_BOOKSLEEVE #if FEATURE_BOOKSLEEVE
[Test] [Test]
[TestCase(true, true, ResultCompletionMode.ConcurrentIfContinuation)] [TestCase(true, true, ResultCompletionMode.ConcurrentIfContinuation)]
[TestCase(true, false, ResultCompletionMode.ConcurrentIfContinuation)] [TestCase(true, false, ResultCompletionMode.ConcurrentIfContinuation)]
[TestCase(false, true, ResultCompletionMode.ConcurrentIfContinuation)] [TestCase(false, true, ResultCompletionMode.ConcurrentIfContinuation)]
[TestCase(false, false, ResultCompletionMode.ConcurrentIfContinuation)] [TestCase(false, false, ResultCompletionMode.ConcurrentIfContinuation)]
[TestCase(true, true, ResultCompletionMode.Concurrent)] [TestCase(true, true, ResultCompletionMode.Concurrent)]
[TestCase(true, false, ResultCompletionMode.Concurrent)] [TestCase(true, false, ResultCompletionMode.Concurrent)]
[TestCase(false, true, ResultCompletionMode.Concurrent)] [TestCase(false, true, ResultCompletionMode.Concurrent)]
[TestCase(false, false, ResultCompletionMode.Concurrent)] [TestCase(false, false, ResultCompletionMode.Concurrent)]
[TestCase(true, true, ResultCompletionMode.PreserveOrder)] [TestCase(true, true, ResultCompletionMode.PreserveOrder)]
[TestCase(true, false, ResultCompletionMode.PreserveOrder)] [TestCase(true, false, ResultCompletionMode.PreserveOrder)]
[TestCase(false, true, ResultCompletionMode.PreserveOrder)] [TestCase(false, true, ResultCompletionMode.PreserveOrder)]
[TestCase(false, false, ResultCompletionMode.PreserveOrder)] [TestCase(false, false, ResultCompletionMode.PreserveOrder)]
public void MassiveBulkOpsAsyncOldStyle(bool withContinuation, bool suspendFlush, ResultCompletionMode completionMode) public void MassiveBulkOpsAsyncOldStyle(bool withContinuation, bool suspendFlush, ResultCompletionMode completionMode)
{ {
using (var conn = GetOldStyleConnection()) using (var conn = GetOldStyleConnection())
{ {
const int db = 0; const int db = 0;
string key = "MBOQ"; string key = "MBOQ";
conn.CompletionMode = completionMode; conn.CompletionMode = completionMode;
conn.Wait(conn.Server.Ping()); conn.Wait(conn.Server.Ping());
Action<Task> nonTrivial = delegate Action<Task> nonTrivial = delegate
{ {
Thread.SpinWait(5); Thread.SpinWait(5);
}; };
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
if (suspendFlush) conn.SuspendFlush(); if (suspendFlush) conn.SuspendFlush();
try try
{ {
for (int i = 0; i <= AsyncOpsQty; i++) for (int i = 0; i <= AsyncOpsQty; i++)
{ {
var t = conn.Strings.Set(db, key, i); var t = conn.Strings.Set(db, key, i);
if (withContinuation) t.ContinueWith(nonTrivial); if (withContinuation) t.ContinueWith(nonTrivial);
} }
} finally } finally
{ {
if (suspendFlush) conn.ResumeFlush(); if (suspendFlush) conn.ResumeFlush();
} }
int val = (int)conn.Wait(conn.Strings.GetInt64(db, key)); int val = (int)conn.Wait(conn.Strings.GetInt64(db, key));
Assert.AreEqual(AsyncOpsQty, val); Assert.AreEqual(AsyncOpsQty, val);
watch.Stop(); watch.Stop();
Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}, {5}); ops/s: {6}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(), Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}, {5}); ops/s: {6}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(),
withContinuation ? "with continuation" : "no continuation", withContinuation ? "with continuation" : "no continuation",
suspendFlush ? "suspend flush" : "flush at whim", suspendFlush ? "suspend flush" : "flush at whim",
completionMode, AsyncOpsQty / watch.Elapsed.TotalSeconds); completionMode, AsyncOpsQty / watch.Elapsed.TotalSeconds);
} }
} }
#endif #endif
[Test] [Test]
[TestCase(true, 1)] [TestCase(true, 1)]
[TestCase(false, 1)] [TestCase(false, 1)]
[TestCase(true, 5)] [TestCase(true, 5)]
[TestCase(false, 5)] [TestCase(false, 5)]
[TestCase(true, 10)] [TestCase(true, 10)]
[TestCase(false, 10)] [TestCase(false, 10)]
[TestCase(true, 50)] [TestCase(true, 50)]
[TestCase(false, 50)] [TestCase(false, 50)]
public void MassiveBulkOpsSync(bool preserveOrder, int threads) public void MassiveBulkOpsSync(bool preserveOrder, int threads)
{ {
int workPerThread = SyncOpsQty / threads; int workPerThread = SyncOpsQty / threads;
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
RedisKey key = "MBOS"; RedisKey key = "MBOS";
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
conn.KeyDelete(key); conn.KeyDelete(key);
#if DEBUG #if DEBUG
long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount();
long oldWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); long oldWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount();
#endif #endif
var timeTaken = RunConcurrent(delegate var timeTaken = RunConcurrent(delegate
{ {
for (int i = 0; i < workPerThread; i++) for (int i = 0; i < workPerThread; i++)
{ {
conn.StringIncrement(key); conn.StringIncrement(key);
} }
}, threads); }, threads);
int val = (int)conn.StringGet(key); int val = (int)conn.StringGet(key);
Assert.AreEqual(workPerThread * threads, val); Assert.AreEqual(workPerThread * threads, val);
Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}", Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}",
threads * workPerThread, timeTaken.TotalMilliseconds, Me() threads * workPerThread, timeTaken.TotalMilliseconds, Me()
, preserveOrder ? "preserve order" : "any order", threads, (workPerThread * threads) / timeTaken.TotalSeconds); , preserveOrder ? "preserve order" : "any order", threads, (workPerThread * threads) / timeTaken.TotalSeconds);
#if DEBUG #if DEBUG
long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount();
long newWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); long newWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount();
Console.WriteLine("ResultBox allocations: {0}; workers {1}", newAlloc - oldAlloc, newWorkerCount - oldWorkerCount); Console.WriteLine("ResultBox allocations: {0}; workers {1}", newAlloc - oldAlloc, newWorkerCount - oldWorkerCount);
Assert.IsTrue(newAlloc - oldAlloc <= 2 * threads, "number of box allocations"); Assert.IsTrue(newAlloc - oldAlloc <= 2 * threads, "number of box allocations");
#endif #endif
} }
} }
#if FEATURE_BOOKSLEEVE #if FEATURE_BOOKSLEEVE
[Test] [Test]
[TestCase(ResultCompletionMode.Concurrent, 1)] [TestCase(ResultCompletionMode.Concurrent, 1)]
[TestCase(ResultCompletionMode.ConcurrentIfContinuation, 1)] [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 1)]
[TestCase(ResultCompletionMode.PreserveOrder, 1)] [TestCase(ResultCompletionMode.PreserveOrder, 1)]
[TestCase(ResultCompletionMode.Concurrent, 5)] [TestCase(ResultCompletionMode.Concurrent, 5)]
[TestCase(ResultCompletionMode.ConcurrentIfContinuation, 5)] [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 5)]
[TestCase(ResultCompletionMode.PreserveOrder, 5)] [TestCase(ResultCompletionMode.PreserveOrder, 5)]
[TestCase(ResultCompletionMode.Concurrent, 10)] [TestCase(ResultCompletionMode.Concurrent, 10)]
[TestCase(ResultCompletionMode.ConcurrentIfContinuation, 10)] [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 10)]
[TestCase(ResultCompletionMode.PreserveOrder, 10)] [TestCase(ResultCompletionMode.PreserveOrder, 10)]
[TestCase(ResultCompletionMode.Concurrent, 50)] [TestCase(ResultCompletionMode.Concurrent, 50)]
[TestCase(ResultCompletionMode.ConcurrentIfContinuation, 50)] [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 50)]
[TestCase(ResultCompletionMode.PreserveOrder, 50)] [TestCase(ResultCompletionMode.PreserveOrder, 50)]
public void MassiveBulkOpsSyncOldStyle(ResultCompletionMode completionMode, int threads) public void MassiveBulkOpsSyncOldStyle(ResultCompletionMode completionMode, int threads)
{ {
int workPerThread = SyncOpsQty / threads; int workPerThread = SyncOpsQty / threads;
using (var conn = GetOldStyleConnection()) using (var conn = GetOldStyleConnection())
{ {
const int db = 0; const int db = 0;
string key = "MBOQ"; string key = "MBOQ";
conn.CompletionMode = completionMode; conn.CompletionMode = completionMode;
conn.Wait(conn.Keys.Remove(db, key)); conn.Wait(conn.Keys.Remove(db, key));
var timeTaken = RunConcurrent(delegate var timeTaken = RunConcurrent(delegate
{ {
for (int i = 0; i < workPerThread; i++) for (int i = 0; i < workPerThread; i++)
{ {
conn.Wait(conn.Strings.Increment(db, key)); conn.Wait(conn.Strings.Increment(db, key));
} }
}, threads); }, threads);
int val = (int)conn.Wait(conn.Strings.GetInt64(db, key)); int val = (int)conn.Wait(conn.Strings.GetInt64(db, key));
Assert.AreEqual(workPerThread * threads, val); Assert.AreEqual(workPerThread * threads, val);
Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}", workPerThread * threads, timeTaken.TotalMilliseconds, Me(), Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}", workPerThread * threads, timeTaken.TotalMilliseconds, Me(),
completionMode, threads, (workPerThread * threads) / timeTaken.TotalSeconds); completionMode, threads, (workPerThread * threads) / timeTaken.TotalSeconds);
} }
} }
#endif #endif
[Test] [Test]
[TestCase(true, 1)] [TestCase(true, 1)]
[TestCase(false, 1)] [TestCase(false, 1)]
[TestCase(true, 5)] [TestCase(true, 5)]
[TestCase(false, 5)] [TestCase(false, 5)]
public void MassiveBulkOpsFireAndForget(bool preserveOrder, int threads) public void MassiveBulkOpsFireAndForget(bool preserveOrder, int threads)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
#if DEBUG #if DEBUG
long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount();
#endif #endif
RedisKey key = "MBOF"; RedisKey key = "MBOF";
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
conn.Ping(); conn.Ping();
conn.KeyDelete(key, CommandFlags.FireAndForget); conn.KeyDelete(key, CommandFlags.FireAndForget);
int perThread = AsyncOpsQty / threads; int perThread = AsyncOpsQty / threads;
var elapsed = RunConcurrent(delegate var elapsed = RunConcurrent(delegate
{ {
for (int i = 0; i < perThread; i++) for (int i = 0; i < perThread; i++)
{ {
conn.StringIncrement(key, flags: CommandFlags.FireAndForget); conn.StringIncrement(key, flags: CommandFlags.FireAndForget);
} }
conn.Ping(); conn.Ping();
}, threads); }, threads);
var val = (long)conn.StringGet(key); var val = (long)conn.StringGet(key);
Assert.AreEqual(perThread * threads, val); Assert.AreEqual(perThread * threads, val);
Console.WriteLine("{2}: Time for {0} ops over {5} threads: {1:###,###}ms ({3}); ops/s: {4:###,###,##0}", Console.WriteLine("{2}: Time for {0} ops over {5} threads: {1:###,###}ms ({3}); ops/s: {4:###,###,##0}",
val, elapsed.TotalMilliseconds, Me(), val, elapsed.TotalMilliseconds, Me(),
preserveOrder ? "preserve order" : "any order", preserveOrder ? "preserve order" : "any order",
val / elapsed.TotalSeconds, threads); val / elapsed.TotalSeconds, threads);
#if DEBUG #if DEBUG
long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount();
Console.WriteLine("ResultBox allocations: {0}", Console.WriteLine("ResultBox allocations: {0}",
newAlloc - oldAlloc); newAlloc - oldAlloc);
Assert.IsTrue(newAlloc - oldAlloc <= 4); Assert.IsTrue(newAlloc - oldAlloc <= 4);
#endif #endif
} }
} }
#if DEBUG #if DEBUG
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void TestQuit(bool preserveOrder) public void TestQuit(bool preserveOrder)
{ {
SetExpectedAmbientFailureCount(1); SetExpectedAmbientFailureCount(1);
using (var muxer = Create(allowAdmin: true)) using (var muxer = Create(allowAdmin: true))
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = Guid.NewGuid().ToString(); string key = Guid.NewGuid().ToString();
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
db.StringSet(key, key, flags: CommandFlags.FireAndForget); db.StringSet(key, key, flags: CommandFlags.FireAndForget);
GetServer(muxer).Quit(CommandFlags.FireAndForget); GetServer(muxer).Quit(CommandFlags.FireAndForget);
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
try try
{ {
db.Ping(); db.Ping();
Assert.Fail(); Assert.Fail();
} }
catch (RedisConnectionException) { } catch (RedisConnectionException) { }
watch.Stop(); watch.Stop();
Console.WriteLine("Time to notice quit: {0}ms ({1})", watch.ElapsedMilliseconds, Console.WriteLine("Time to notice quit: {0}ms ({1})", watch.ElapsedMilliseconds,
preserveOrder ? "preserve order" : "any order"); preserveOrder ? "preserve order" : "any order");
Thread.Sleep(20); Thread.Sleep(20);
Debug.WriteLine("Pinging..."); Debug.WriteLine("Pinging...");
Assert.AreEqual(key, (string)db.StringGet(key)); Assert.AreEqual(key, (string)db.StringGet(key));
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void TestSevered(bool preserveOrder) public void TestSevered(bool preserveOrder)
{ {
SetExpectedAmbientFailureCount(2); SetExpectedAmbientFailureCount(2);
using (var muxer = Create(allowAdmin: true)) using (var muxer = Create(allowAdmin: true))
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
string key = Guid.NewGuid().ToString(); string key = Guid.NewGuid().ToString();
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
db.StringSet(key, key, flags: CommandFlags.FireAndForget); db.StringSet(key, key, flags: CommandFlags.FireAndForget);
GetServer(muxer).SimulateConnectionFailure(); GetServer(muxer).SimulateConnectionFailure();
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
db.Ping(); db.Ping();
watch.Stop(); watch.Stop();
Console.WriteLine("Time to re-establish: {0}ms ({1})", watch.ElapsedMilliseconds, Console.WriteLine("Time to re-establish: {0}ms ({1})", watch.ElapsedMilliseconds,
preserveOrder ? "preserve order" : "any order"); preserveOrder ? "preserve order" : "any order");
Thread.Sleep(20); Thread.Sleep(20);
Debug.WriteLine("Pinging..."); Debug.WriteLine("Pinging...");
Assert.AreEqual(key, (string)db.StringGet(key)); Assert.AreEqual(key, (string)db.StringGet(key));
} }
} }
#endif #endif
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void IncrAsync(bool preserveOrder) public void IncrAsync(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
conn.KeyDelete(key, CommandFlags.FireAndForget); conn.KeyDelete(key, CommandFlags.FireAndForget);
var nix = conn.KeyExistsAsync(key); var nix = conn.KeyExistsAsync(key);
var a = conn.StringGetAsync(key); var a = conn.StringGetAsync(key);
var b = conn.StringIncrementAsync(key); var b = conn.StringIncrementAsync(key);
var c = conn.StringGetAsync(key); var c = conn.StringGetAsync(key);
var d = conn.StringIncrementAsync(key, 10); var d = conn.StringIncrementAsync(key, 10);
var e = conn.StringGetAsync(key); var e = conn.StringGetAsync(key);
var f = conn.StringDecrementAsync(key, 11); var f = conn.StringDecrementAsync(key, 11);
var g = conn.StringGetAsync(key); var g = conn.StringGetAsync(key);
var h = conn.KeyExistsAsync(key); var h = conn.KeyExistsAsync(key);
Assert.IsFalse(muxer.Wait(nix)); Assert.IsFalse(muxer.Wait(nix));
Assert.IsTrue(muxer.Wait(a).IsNull); Assert.IsTrue(muxer.Wait(a).IsNull);
Assert.AreEqual(0, (long)muxer.Wait(a)); Assert.AreEqual(0, (long)muxer.Wait(a));
Assert.AreEqual(1, muxer.Wait(b)); Assert.AreEqual(1, muxer.Wait(b));
Assert.AreEqual(1, (long)muxer.Wait(c)); Assert.AreEqual(1, (long)muxer.Wait(c));
Assert.AreEqual(11, muxer.Wait(d)); Assert.AreEqual(11, muxer.Wait(d));
Assert.AreEqual(11, (long)muxer.Wait(e)); Assert.AreEqual(11, (long)muxer.Wait(e));
Assert.AreEqual(0, muxer.Wait(f)); Assert.AreEqual(0, muxer.Wait(f));
Assert.AreEqual(0, (long)muxer.Wait(g)); Assert.AreEqual(0, (long)muxer.Wait(g));
Assert.IsTrue(muxer.Wait(h)); Assert.IsTrue(muxer.Wait(h));
} }
} }
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public void IncrSync(bool preserveOrder) public void IncrSync(bool preserveOrder)
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
muxer.PreserveAsyncOrder = preserveOrder; muxer.PreserveAsyncOrder = preserveOrder;
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
conn.KeyDelete(key, CommandFlags.FireAndForget); conn.KeyDelete(key, CommandFlags.FireAndForget);
var nix = conn.KeyExists(key); var nix = conn.KeyExists(key);
var a = conn.StringGet(key); var a = conn.StringGet(key);
var b = conn.StringIncrement(key); var b = conn.StringIncrement(key);
var c = conn.StringGet(key); var c = conn.StringGet(key);
var d = conn.StringIncrement(key, 10); var d = conn.StringIncrement(key, 10);
var e = conn.StringGet(key); var e = conn.StringGet(key);
var f = conn.StringDecrement(key, 11); var f = conn.StringDecrement(key, 11);
var g = conn.StringGet(key); var g = conn.StringGet(key);
var h = conn.KeyExists(key); var h = conn.KeyExists(key);
Assert.IsFalse(nix); Assert.IsFalse(nix);
Assert.IsTrue(a.IsNull); Assert.IsTrue(a.IsNull);
Assert.AreEqual(0, (long)a); Assert.AreEqual(0, (long)a);
Assert.AreEqual(1, b); Assert.AreEqual(1, b);
Assert.AreEqual(1, (long)c); Assert.AreEqual(1, (long)c);
Assert.AreEqual(11, d); Assert.AreEqual(11, d);
Assert.AreEqual(11, (long)e); Assert.AreEqual(11, (long)e);
Assert.AreEqual(0, f); Assert.AreEqual(0, f);
Assert.AreEqual(0, (long)g); Assert.AreEqual(0, (long)g);
Assert.IsTrue(h); Assert.IsTrue(h);
} }
} }
[Test] [Test]
public void IncrDifferentSizes() public void IncrDifferentSizes()
{ {
using (var muxer = Create()) using (var muxer = Create())
{ {
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
RedisKey key = Me(); RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget); db.KeyDelete(key, CommandFlags.FireAndForget);
int expected = 0; int expected = 0;
Incr(db, key, -129019, ref expected); Incr(db, key, -129019, ref expected);
Incr(db, key, -10023, ref expected); Incr(db, key, -10023, ref expected);
Incr(db, key, -9933, ref expected); Incr(db, key, -9933, ref expected);
Incr(db, key, -23, ref expected); Incr(db, key, -23, ref expected);
Incr(db, key, -7, ref expected); Incr(db, key, -7, ref expected);
Incr(db, key, -1, ref expected); Incr(db, key, -1, ref expected);
Incr(db, key, 0, ref expected); Incr(db, key, 0, ref expected);
Incr(db, key, 1, ref expected); Incr(db, key, 1, ref expected);
Incr(db, key, 9, ref expected); Incr(db, key, 9, ref expected);
Incr(db, key, 11, ref expected); Incr(db, key, 11, ref expected);
Incr(db, key, 345, ref expected); Incr(db, key, 345, ref expected);
Incr(db, key, 4982, ref expected); Incr(db, key, 4982, ref expected);
Incr(db, key, 13091, ref expected); Incr(db, key, 13091, ref expected);
Incr(db, key, 324092, ref expected); Incr(db, key, 324092, ref expected);
Assert.AreNotEqual(0, expected); Assert.AreNotEqual(0, expected);
var sum = (long)db.StringGet(key); var sum = (long)db.StringGet(key);
Assert.AreEqual(expected, sum); Assert.AreEqual(expected, sum);
} }
} }
private void Incr(IDatabase database, RedisKey key, int delta, ref int total) private void Incr(IDatabase database, RedisKey key, int delta, ref int total)
{ {
database.StringIncrement(key, delta, CommandFlags.FireAndForget); database.StringIncrement(key, delta, CommandFlags.FireAndForget);
total += delta; total += delta;
} }
[Test] [Test]
public void WrappedDatabasePrefixIntegration() public void WrappedDatabasePrefixIntegration()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var db = conn.GetDatabase().WithKeyPrefix("abc"); var db = conn.GetDatabase().WithKeyPrefix("abc");
db.KeyDelete("count"); db.KeyDelete("count");
db.StringIncrement("count"); db.StringIncrement("count");
db.StringIncrement("count"); db.StringIncrement("count");
db.StringIncrement("count"); db.StringIncrement("count");
int count = (int)conn.GetDatabase().StringGet("abccount"); int count = (int)conn.GetDatabase().StringGet("abccount");
Assert.AreEqual(3, count); Assert.AreEqual(3, count);
} }
} }
} }
} }
...@@ -20,7 +20,7 @@ public class Cluster : TestBase ...@@ -20,7 +20,7 @@ public class Cluster : TestBase
protected override string GetConfiguration() protected override string GetConfiguration()
{ {
var server = ClusterIp; var server = ClusterIp;
#if !DNXCORE50 #if !CORE_CLR
if (string.Equals(Environment.MachineName, "MARC-LAPTOP", StringComparison.InvariantCultureIgnoreCase)) if (string.Equals(Environment.MachineName, "MARC-LAPTOP", StringComparison.InvariantCultureIgnoreCase))
#else #else
if (string.Equals(Environment.GetEnvironmentVariable("COMPUTERNAME"), "MARC-LAPTOP", StringComparison.OrdinalIgnoreCase)) if (string.Equals(Environment.GetEnvironmentVariable("COMPUTERNAME"), "MARC-LAPTOP", StringComparison.OrdinalIgnoreCase))
......
...@@ -147,7 +147,7 @@ public void ReadConfig() ...@@ -147,7 +147,7 @@ public void ReadConfig()
var all = conn.ConfigGet(); var all = conn.ConfigGet();
Assert.IsTrue(all.Length > 0, "any"); Assert.IsTrue(all.Length > 0, "any");
#if !DNXCORE50 #if !CORE_CLR
var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.InvariantCultureIgnoreCase); var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.InvariantCultureIgnoreCase);
#else #else
var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.OrdinalIgnoreCase); var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.OrdinalIgnoreCase);
......
...@@ -150,7 +150,7 @@ public void CheckSyncAsyncMethodsMatch(Type from, Type to) ...@@ -150,7 +150,7 @@ public void CheckSyncAsyncMethodsMatch(Type from, Type to)
var pFrom = method.GetParameters(); var pFrom = method.GetParameters();
Type[] args = pFrom.Select(x => x.ParameterType).ToArray(); Type[] args = pFrom.Select(x => x.ParameterType).ToArray();
Assert.AreEqual(typeof(CommandFlags), args.Last()); Assert.AreEqual(typeof(CommandFlags), args.Last());
#if !DNXCORE50 #if !CORE_CLR
var found = to.GetMethod(huntName, flags, null, method.CallingConvention, args, null); var found = to.GetMethod(huntName, flags, null, method.CallingConvention, args, null);
#else #else
var found = to.GetMethods(flags) var found = to.GetMethods(flags)
...@@ -176,14 +176,14 @@ void CheckMethod(MethodInfo method, bool isAsync) ...@@ -176,14 +176,14 @@ void CheckMethod(MethodInfo method, bool isAsync)
{ {
#if DEBUG #if DEBUG
#if !DNXCORE50 #if !CORE_CLR
bool ignorePrefix = ignoreType != null && Attribute.IsDefined(method, ignoreType); bool ignorePrefix = ignoreType != null && Attribute.IsDefined(method, ignoreType);
#else #else
bool ignorePrefix = ignoreType != null && method.IsDefined(ignoreType); bool ignorePrefix = ignoreType != null && method.IsDefined(ignoreType);
#endif #endif
if (ignorePrefix) if (ignorePrefix)
{ {
#if !DNXCORE50 #if !CORE_CLR
Attribute attrib = Attribute.GetCustomAttribute(method, ignoreType); Attribute attrib = Attribute.GetCustomAttribute(method, ignoreType);
#else #else
Attribute attrib = method.GetCustomAttribute(ignoreType); Attribute attrib = method.GetCustomAttribute(ignoreType);
...@@ -228,7 +228,7 @@ void CheckName(MemberInfo member, bool isAsync) ...@@ -228,7 +228,7 @@ void CheckName(MemberInfo member, bool isAsync)
public static class ReflectionExtensions public static class ReflectionExtensions
{ {
#if !DNXCORE50 #if !CORE_CLR
public static Type GetTypeInfo(this Type type) public static Type GetTypeInfo(this Type type)
{ {
return type; return type;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
#if DNXCORE50 #if CORE_CLR
using System.Reflection; using System.Reflection;
#endif #endif
using System.Threading.Tasks; using System.Threading.Tasks;
......
#if NUNITLITE
using System; using System;
using System.Reflection; using System.Reflection;
using NUnitLite; using NUnitLite;
...@@ -11,4 +12,5 @@ public int Main(string[] args) ...@@ -11,4 +12,5 @@ public int Main(string[] args)
return new AutoRun().Execute(typeof(TestBase).GetTypeInfo().Assembly, Console.Out, Console.In, args); return new AutoRun().Execute(typeof(TestBase).GetTypeInfo().Assembly, Console.Out, Console.In, args);
} }
} }
} }
\ No newline at end of file #endif
\ No newline at end of file
...@@ -417,7 +417,7 @@ internal static class VolatileWrapper ...@@ -417,7 +417,7 @@ internal static class VolatileWrapper
{ {
public static int Read(ref int location) public static int Read(ref int location)
{ {
#if !DNXCORE50 #if !CORE_CLR
return Thread.VolatileRead(ref location); return Thread.VolatileRead(ref location);
#else #else
return Volatile.Read(ref location); return Volatile.Read(ref location);
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>a51dca17-e8f1-44e1-9a37-328fab14d2ce</ProjectGuid> <ProjectGuid>3b8bd8f1-8bfc-4d8c-b4da-25ffaf3d1dbe</ProjectGuid>
<RootNamespace>StackExchange.Redis.Tests</RootNamespace> <RootNamespace>StackExchange.Redis.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\StackExchange.Redis_dnxcore50\StackExchange.Redis\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath> <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\StackExchange.Redis_dnxcore50\StackExchange.Redis\artifacts\bin\$(MSBuildProjectName)\</OutputPath> <OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
......
...@@ -246,7 +246,7 @@ private static RedisConnection GetOldStyleConnection(string host, int port, bool ...@@ -246,7 +246,7 @@ private static RedisConnection GetOldStyleConnection(string host, int port, bool
protected static TimeSpan RunConcurrent(Action work, int threads, int timeout = 10000, [CallerMemberName] string caller = null) protected static TimeSpan RunConcurrent(Action work, int threads, int timeout = 10000, [CallerMemberName] string caller = null)
{ {
if (work == null) throw new ArgumentNullException("work"); if (work == null) throw new ArgumentNullException("work");
if (threads < 1) throw new ArgumentOutOfRangeException("theads"); if (threads < 1) throw new ArgumentOutOfRangeException("threads");
if(string.IsNullOrWhiteSpace(caller)) caller = Me(); if(string.IsNullOrWhiteSpace(caller)) caller = Me();
Stopwatch watch = null; Stopwatch watch = null;
ManualResetEvent allDone = new ManualResetEvent(false); ManualResetEvent allDone = new ManualResetEvent(false);
...@@ -285,7 +285,7 @@ protected static TimeSpan RunConcurrent(Action work, int threads, int timeout = ...@@ -285,7 +285,7 @@ protected static TimeSpan RunConcurrent(Action work, int threads, int timeout =
} }
if (!allDone.WaitOne(timeout)) if (!allDone.WaitOne(timeout))
{ {
#if !DNXCORE50 #if !CORE_CLR
for (int i = 0; i < threads; i++) for (int i = 0; i < threads; i++)
{ {
var thd = threadArr[i]; var thd = threadArr[i];
......
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using StackExchange.Redis.KeyspaceIsolation; using StackExchange.Redis.KeyspaceIsolation;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
{ {
[TestFixture] [TestFixture]
public class WithKeyPrefixTests : TestBase public class WithKeyPrefixTests : TestBase
{ {
[Test] [Test]
public void BlankPrefixYieldsSame_Bytes() public void BlankPrefixYieldsSame_Bytes()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var raw = conn.GetDatabase(1); var raw = conn.GetDatabase(1);
var prefixed = raw.WithKeyPrefix(new byte[0]); var prefixed = raw.WithKeyPrefix(new byte[0]);
Assert.AreSame(raw, prefixed); Assert.AreSame(raw, prefixed);
} }
} }
[Test] [Test]
public void BlankPrefixYieldsSame_String() public void BlankPrefixYieldsSame_String()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
var raw = conn.GetDatabase(1); var raw = conn.GetDatabase(1);
var prefixed = raw.WithKeyPrefix(""); var prefixed = raw.WithKeyPrefix("");
Assert.AreSame(raw, prefixed); Assert.AreSame(raw, prefixed);
} }
} }
[Test] [Test]
public void NullPrefixIsError_Bytes() public void NullPrefixIsError_Bytes()
{ {
Assert.Throws<ArgumentNullException>(() => { Assert.Throws<ArgumentNullException>(() => {
using (var conn = Create()) using (var conn = Create())
{ {
var raw = conn.GetDatabase(1); var raw = conn.GetDatabase(1);
var prefixed = raw.WithKeyPrefix((byte[])null); var prefixed = raw.WithKeyPrefix((byte[])null);
} }
}); });
} }
[Test]
[Test] public void NullPrefixIsError_String()
public void NullPrefixIsError_String() {
{ Assert.Throws<ArgumentNullException>(() => {
Assert.Throws<ArgumentNullException>(() => { using (var conn = Create())
using (var conn = Create()) {
{ var raw = conn.GetDatabase(1);
var raw = conn.GetDatabase(1); var prefixed = raw.WithKeyPrefix((string)null);
var prefixed = raw.WithKeyPrefix((string)null); }
} });
}); }
}
[Test]
[Test] [TestCase("abc")]
[TestCase("abc")] [TestCase("")]
[TestCase("")] [TestCase(null)]
[TestCase(null)] public void NullDatabaseIsError(string prefix)
public void NullDatabaseIsError(string prefix) {
{ Assert.Throws<ArgumentNullException>(() => {
Assert.Throws<ArgumentNullException>(() => { IDatabase raw = null;
IDatabase raw = null; var prefixed = raw.WithKeyPrefix(prefix);
var prefixed = raw.WithKeyPrefix(prefix); });
}); }
} [Test]
public void BasicSmokeTest()
[Test] {
public void BasicSmokeTest() using(var conn = Create())
{ {
using(var conn = Create()) var raw = conn.GetDatabase(1);
{
var raw = conn.GetDatabase(1); var foo = raw.WithKeyPrefix("foo");
var foobar = foo.WithKeyPrefix("bar");
var foo = raw.WithKeyPrefix("foo");
var foobar = foo.WithKeyPrefix("bar"); string key = Me();
string key = Me(); string s = Guid.NewGuid().ToString(), t = Guid.NewGuid().ToString();
string s = Guid.NewGuid().ToString(), t = Guid.NewGuid().ToString(); foo.StringSet(key, s);
var val = (string)foo.StringGet(key);
foo.StringSet(key, s); Assert.AreEqual(s, val); // fooBasicSmokeTest
var val = (string)foo.StringGet(key);
Assert.AreEqual(s, val); // fooBasicSmokeTest foobar.StringSet(key, t);
val = (string)foobar.StringGet(key);
foobar.StringSet(key, t); Assert.AreEqual(t, val); // foobarBasicSmokeTest
val = (string)foobar.StringGet(key);
Assert.AreEqual(t, val); // foobarBasicSmokeTest val = (string)foo.StringGet("bar" + key);
Assert.AreEqual(t, val); // foobarBasicSmokeTest
val = (string)foo.StringGet("bar" + key);
Assert.AreEqual(t, val); // foobarBasicSmokeTest val = (string)raw.StringGet("foo" + key);
Assert.AreEqual(s, val); // fooBasicSmokeTest
val = (string)raw.StringGet("foo" + key);
Assert.AreEqual(s, val); // fooBasicSmokeTest val = (string)raw.StringGet("foobar" + key);
Assert.AreEqual(t, val); // foobarBasicSmokeTest
val = (string)raw.StringGet("foobar" + key); }
Assert.AreEqual(t, val); // foobarBasicSmokeTest }
} [Test]
} public void ConditionTest()
[Test] {
public void ConditionTest() using(var conn = Create())
{ {
using(var conn = Create()) var raw = conn.GetDatabase(2);
{
var raw = conn.GetDatabase(2); var foo = raw.WithKeyPrefix("tran:");
var foo = raw.WithKeyPrefix("tran:"); raw.KeyDelete("tran:abc");
raw.KeyDelete("tran:i");
raw.KeyDelete("tran:abc");
raw.KeyDelete("tran:i"); // execute while key exists
raw.StringSet("tran:abc", "def");
// execute while key exists var tran = foo.CreateTransaction();
raw.StringSet("tran:abc", "def"); tran.AddCondition(Condition.KeyExists("abc"));
var tran = foo.CreateTransaction(); tran.StringIncrementAsync("i");
tran.AddCondition(Condition.KeyExists("abc")); tran.Execute();
tran.StringIncrementAsync("i");
tran.Execute(); int i = (int)raw.StringGet("tran:i");
Assert.AreEqual(1, i);
int i = (int)raw.StringGet("tran:i");
Assert.AreEqual(1, i); // repeat without key
raw.KeyDelete("tran:abc");
// repeat without key tran = foo.CreateTransaction();
raw.KeyDelete("tran:abc"); tran.AddCondition(Condition.KeyExists("abc"));
tran = foo.CreateTransaction(); tran.StringIncrementAsync("i");
tran.AddCondition(Condition.KeyExists("abc")); tran.Execute();
tran.StringIncrementAsync("i");
tran.Execute(); i = (int)raw.StringGet("tran:i");
Assert.AreEqual(1, i);
i = (int)raw.StringGet("tran:i"); }
Assert.AreEqual(1, i); }
} }
} }
}
}
...@@ -16,7 +16,6 @@ public sealed class WrapperBaseTests ...@@ -16,7 +16,6 @@ public sealed class WrapperBaseTests
private Mock<IDatabaseAsync> mock; private Mock<IDatabaseAsync> mock;
private WrapperBase<IDatabaseAsync> wrapper; private WrapperBase<IDatabaseAsync> wrapper;
//[TestFixtureSetUp]
[OneTimeSetUp] [OneTimeSetUp]
public void Initialize() public void Initialize()
{ {
...@@ -891,4 +890,4 @@ public void StringSetRangeAsync() ...@@ -891,4 +890,4 @@ public void StringSetRangeAsync()
} }
} }
} }
#endif #endif
\ No newline at end of file
{ {
"version": "1.0.0-*", "version": "1.0.0-*",
"description": "StackExchange.Redis.Tests", "description": "StackExchange.Redis.Tests",
"authors": [ "jeremymeng" ], "authors": [ "" ],
"tags": [ "" ], "tags": [ "" ],
"projectUrl": "", "projectUrl": "",
"licenseUrl": "", "licenseUrl": "",
"compile": [
"../../StackExchange.Redis.Tests/**/*.cs"
],
"dependencies": { "dependencies": {
"StackExchange.Redis": "1.1.0-*" "StackExchange.Redis": {
"version": "1.1.0-alpha1",
"target": "project"
}
}, },
"commands": { "commands": {
"run": "StackExchange.Redis.Tests" "run": "StackExchange.Redis.Tests"
}, },
"compilationOptions": { "define": [ "NUNITLITE" ] },
"configurations": {
"Debug": {
"compilationOptions": {
"define": [ "DEBUG", "TRACE", "PLAT_SAFE_CONTINUATIONS" ]
}
},
"Release": {
"compilationOptions": {
"define": [ "TRACE", "PLAT_SAFE_CONTINUATIONS" ]
}
}
},
"frameworks": { "frameworks": {
"dnxcore50": { "dnxcore50": {
"compilationOptions": { "define": [ "PLAT_SAFE_CONTINUATIONS", "CORE_CLR" ] },
"dependencies": { "dependencies": {
"System.Console": "4.0.0-beta-*", "System.Console": "4.0.0-beta-23516",
"System.Linq.Expressions": "4.0.11-beta-23409", "System.Linq.Expressions": "4.0.11-beta-23516",
"System.Reflection.Extensions": "4.0.1-beta-23409", "System.Reflection.Extensions": "4.0.1-beta-23516",
"System.Threading.Tasks.Parallel": "4.0.1-beta-23409", "System.Threading.Tasks.Parallel": "4.0.1-beta-23516",
"Microsoft.CSharp": "4.0.1-beta-23409", "Microsoft.CSharp": "4.0.1-beta-23516",
"nunitlite": "3.0.0" "nunitlite": "3.0.0"
} }
} }
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{19C00111-1328-4089-8565-94920B5B47F2}</ProjectGuid> <ProjectGuid>{19C00111-1328-4089-8565-94920B5B47F2}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>StackExchange.Redis.Tests</RootNamespace> <RootNamespace>StackExchange.Redis.Tests</RootNamespace>
<AssemblyName>StackExchange.Redis.Tests</AssemblyName> <AssemblyName>StackExchange.Redis.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;PLAT_SAFE_CONTINUATIONS;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants> <DefineConstants>TRACE;DEBUG;PLAT_SAFE_CONTINUATIONS;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks> <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath> <OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;PLAT_SAFE_CONTINUATIONS;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants> <DefineConstants>TRACE;PLAT_SAFE_CONTINUATIONS;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Verbose\</OutputPath> <OutputPath>bin\Verbose\</OutputPath>
<DefineConstants>TRACE;DEBUG;VERBOSE;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants> <DefineConstants>TRACE;DEBUG;VERBOSE;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Log Output\</OutputPath> <OutputPath>bin\Log Output\</OutputPath>
<DefineConstants>TRACE;DEBUG;LOGOUTPUT;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants> <DefineConstants>TRACE;DEBUG;LOGOUTPUT;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
<DefineConstants>TRACE;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants> <DefineConstants>TRACE;FEATURE_BOOKSLEEVE;FEATURE_MOQ</DefineConstants>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="BookSleeve"> <Reference Include="BookSleeve">
<HintPath>..\packages\BookSleeve.1.3.41\lib\BookSleeve.dll</HintPath> <HintPath>..\packages\BookSleeve.1.3.41\lib\BookSleeve.dll</HintPath>
</Reference> </Reference>
<Reference Include="Moq, Version=4.2.1502.911, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.2.1502.911, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.2.1502.0911\lib\net40\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.2.1502.0911\lib\net40\Moq.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.0.5797.27534, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.0.5797.27534, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.0.0\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.0.0\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AsyncTests.cs" /> <Compile Include="..\StackExchange.Redis.Tests\**\*.cs"/>
<Compile Include="BasicOps.cs" /> </ItemGroup>
<Compile Include="ConnectingFailDetection.cs" /> <ItemGroup>
<Compile Include="ConnectToUnexistingHost.cs" /> <None Include="packages.config">
<Compile Include="HyperLogLog.cs" /> <SubType>Designer</SubType>
<Compile Include="Issues\DefaultDatabase.cs" /> </None>
<Compile Include="Profiling.cs" /> </ItemGroup>
<Compile Include="Issues\Issue182.cs" /> <ItemGroup>
<Compile Include="WrapperBaseTests.cs" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
<Compile Include="TransactionWrapperTests.cs" /> </ItemGroup>
<Compile Include="Bits.cs" /> <ItemGroup>
<Compile Include="Cluster.cs" /> <ProjectReference Include="..\StackExchange.Redis_Net46\StackExchange.Redis_Net46.csproj">
<Compile Include="Commands.cs" /> <Project>{8c473a6f-b0de-4add-88f8-c41b441e407c}</Project>
<Compile Include="ConnectFailTimeout.cs" /> <Name>StackExchange.Redis_Net46</Name>
<Compile Include="ConnectionShutdown.cs" /> </ProjectReference>
<Compile Include="Databases.cs" /> </ItemGroup>
<Compile Include="BatchWrapperTests.cs" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Compile Include="DatabaseWrapperTests.cs" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<Compile Include="DefaultPorts.cs" /> Other similar extension points exist, see Microsoft.Common.targets.
<Compile Include="Expiry.cs" /> <Target Name="BeforeBuild">
<Compile Include="Config.cs" /> </Target>
<Compile Include="FloatingPoint.cs" /> <Target Name="AfterBuild">
<Compile Include="Issues\BGSAVEResponse.cs" /> </Target>
<Compile Include="Issues\Issue25.cs" /> -->
<Compile Include="Issues\Issue6.cs" />
<Compile Include="Issues\SO22786599.cs" />
<Compile Include="Issues\SO23949477.cs" />
<Compile Include="Issues\SO24807536.cs" />
<Compile Include="Issues\SO25567566.cs" />
<Compile Include="Keys.cs" />
<Compile Include="KeysAndValues.cs" />
<Compile Include="Lex.cs" />
<Compile Include="Lists.cs" />
<Compile Include="Locking.cs" />
<Compile Include="Migrate.cs" />
<Compile Include="MultiAdd.cs" />
<Compile Include="MultiMaster.cs" />
<Compile Include="Naming.cs" />
<Compile Include="PreserveOrder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PubSub.cs" />
<Compile Include="PubSubCommand.cs" />
<Compile Include="RealWorld.cs" />
<Compile Include="Scans.cs" />
<Compile Include="Scripting.cs" />
<Compile Include="Secure.cs" />
<Compile Include="Sentinel.cs" />
<Compile Include="Sets.cs" />
<Compile Include="Issues\SO25113323.cs" />
<Compile Include="SSDB.cs" />
<Compile Include="SSL.cs" />
<Compile Include="TaskTests.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestInfoReplicationChecks.cs" />
<Compile Include="Transactions.cs" />
<Compile Include="VPNTest.cs" />
<Compile Include="WithKeyPrefixTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StackExchange.Redis_Net46\StackExchange.Redis_Net46.csproj">
<Project>{8c473a6f-b0de-4add-88f8-c41b441e407c}</Project>
<Name>StackExchange.Redis_Net46</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project> </Project>
\ No newline at end of file
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.24709.0 VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StackExchange.Redis", "StackExchange.Redis_dnxcore50\StackExchange.Redis\StackExchange.Redis.xproj", "{86526B5C-1163-4481-A5E2-A303A0BB1535}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BasicTest_dnxcore50", "BasicTest_dnxcore50\BasicTest_dnxcore50.xproj", "{9D83BABA-A92E-495F-BF63-DEB4F6B09355}"
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StackExchange.Redis.Tests", "StackExchange.Redis.Tests_dnxcore50\StackExchange.Redis.Tests\StackExchange.Redis.Tests.xproj", "{A51DCA17-E8F1-44E1-9A37-328FAB14D2CE}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StackExchange.Redis", "StackExchange.Redis\StackExchange.Redis.xproj", "{EF84877F-59BE-41BE-9013-E765AF0BB72E}"
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BasicTest_dnxcore50", "BasicTest_dnxcore50\BasicTest_dnxcore50.xproj", "{9D83BABA-A92E-495F-BF63-DEB4F6B09355}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StackExchange.Redis.StrongName", "StackExchange.Redis.StrongName\StackExchange.Redis.StrongName.xproj", "{46754D2A-AC16-4686-B113-3DB08ACF4269}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StackExchange.Redis.Tests", "StackExchange.Redis.Tests\StackExchange.Redis.Tests.xproj", "{3B8BD8F1-8BFC-4D8C-B4DA-25FFAF3D1DBE}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
...@@ -15,18 +17,22 @@ Global ...@@ -15,18 +17,22 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{86526B5C-1163-4481-A5E2-A303A0BB1535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86526B5C-1163-4481-A5E2-A303A0BB1535}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86526B5C-1163-4481-A5E2-A303A0BB1535}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86526B5C-1163-4481-A5E2-A303A0BB1535}.Release|Any CPU.Build.0 = Release|Any CPU
{A51DCA17-E8F1-44E1-9A37-328FAB14D2CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A51DCA17-E8F1-44E1-9A37-328FAB14D2CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A51DCA17-E8F1-44E1-9A37-328FAB14D2CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A51DCA17-E8F1-44E1-9A37-328FAB14D2CE}.Release|Any CPU.Build.0 = Release|Any CPU
{9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Release|Any CPU.Build.0 = Release|Any CPU {9D83BABA-A92E-495F-BF63-DEB4F6B09355}.Release|Any CPU.Build.0 = Release|Any CPU
{EF84877F-59BE-41BE-9013-E765AF0BB72E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF84877F-59BE-41BE-9013-E765AF0BB72E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF84877F-59BE-41BE-9013-E765AF0BB72E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF84877F-59BE-41BE-9013-E765AF0BB72E}.Release|Any CPU.Build.0 = Release|Any CPU
{46754D2A-AC16-4686-B113-3DB08ACF4269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46754D2A-AC16-4686-B113-3DB08ACF4269}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46754D2A-AC16-4686-B113-3DB08ACF4269}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46754D2A-AC16-4686-B113-3DB08ACF4269}.Release|Any CPU.Build.0 = Release|Any CPU
{3B8BD8F1-8BFC-4D8C-B4DA-25FFAF3D1DBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B8BD8F1-8BFC-4D8C-B4DA-25FFAF3D1DBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B8BD8F1-8BFC-4D8C-B4DA-25FFAF3D1DBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B8BD8F1-8BFC-4D8C-B4DA-25FFAF3D1DBE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis.md", "StackExchange.Redis\StackExchange.Redis.md.csproj", "{8EA21FC8-9CF7-438B-94F2-42E3810C3641}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8EA21FC8-9CF7-438B-94F2-42E3810C3641}.Debug|x86.ActiveCfg = Debug|x86
{8EA21FC8-9CF7-438B-94F2-42E3810C3641}.Debug|x86.Build.0 = Debug|x86
{8EA21FC8-9CF7-438B-94F2-42E3810C3641}.Release|x86.ActiveCfg = Release|x86
{8EA21FC8-9CF7-438B-94F2-42E3810C3641}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = StackExchange.Redis.md\StackExchange.Redis.md.csproj
EndGlobalSection
EndGlobal
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<authors>Stack Exchange inc., marc.gravell</authors> <authors>Stack Exchange inc., marc.gravell</authors>
<owners>Stack Exchange inc., marc.gravell</owners> <owners>Stack Exchange inc., marc.gravell</owners>
<summary>Redis client library</summary> <summary>Redis client library</summary>
<description>High performance Redis client, incorporating both synchronous and asynchronous usage; the notional successor to BookSleeve. If you require a strong-named version, try StackExchange.Redis.StrongName</description> <description></description>
<tags>Async Redis NoSQL Client Distributed Cache PubSub Messaging</tags> <tags>Async Redis NoSQL Client Distributed Cache PubSub Messaging</tags>
<language>en-US</language> <language>en-US</language>
<projectUrl>https://github.com/StackExchange/StackExchange.Redis</projectUrl> <projectUrl>https://github.com/StackExchange/StackExchange.Redis</projectUrl>
......
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.24606.1 VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis", "StackExchange.Redis\StackExchange.Redis.csproj", "{7CEC07F2-8C03-4C42-B048-738B215824C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis.Tests", "StackExchange.Redis.Tests\StackExchange.Redis.Tests.csproj", "{19C00111-1328-4089-8565-94920B5B47F2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D3090DF1-8760-4FE2-A595-4C8AC12854ED}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D3090DF1-8760-4FE2-A595-4C8AC12854ED}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.nuget\packages.config = .nuget\packages.config .nuget\packages.config = .nuget\packages.config
...@@ -52,14 +48,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MigratedBookSleeveTestSuite ...@@ -52,14 +48,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MigratedBookSleeveTestSuite
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net40", "StackExchange.Redis_Net40\StackExchange.Redis_Net40.csproj", "{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net40", "StackExchange.Redis_Net40\StackExchange.Redis_Net40.csproj", "{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis.StrongName", "StackExchange.Redis\StackExchange.Redis.StrongName.csproj", "{EBF46088-E318-4D32-9EFB-01EF130A4554}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net40.StrongName", "StackExchange.Redis_Net40\StackExchange.Redis_Net40.StrongName.csproj", "{75CED009-AAC6-4AC1-9C38-A0530619062D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net40.StrongName", "StackExchange.Redis_Net40\StackExchange.Redis_Net40.StrongName.csproj", "{75CED009-AAC6-4AC1-9C38-A0530619062D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net46", "StackExchange.Redis_Net46\StackExchange.Redis_Net46.csproj", "{8C473A6F-B0DE-4ADD-88F8-C41B441E407C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net46", "StackExchange.Redis_Net46\StackExchange.Redis_Net46.csproj", "{8C473A6F-B0DE-4ADD-88F8-C41B441E407C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net46.StrongName", "StackExchange.Redis_Net46\StackExchange.Redis_Net46.StrongName.csproj", "{8CE5D027-E332-42DD-BA54-16310DCD529C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net46.StrongName", "StackExchange.Redis_Net46\StackExchange.Redis_Net46.StrongName.csproj", "{8CE5D027-E332-42DD-BA54-16310DCD529C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net45", "StackExchange.Redis_Net45\StackExchange.Redis_Net45.csproj", "{7CEC07F2-8C03-4C42-B048-738B215824C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis_Net45.StrongName", "StackExchange.Redis_Net45\StackExchange.Redis_Net45.StrongName.csproj", "{EBF46088-E318-4D32-9EFB-01EF130A4554}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis.Tests_Net46", "StackExchange.Redis.Tests_Net46\StackExchange.Redis.Tests_Net46.csproj", "{19C00111-1328-4089-8565-94920B5B47F2}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -69,26 +69,6 @@ Global ...@@ -69,26 +69,6 @@ Global
Verbose|Any CPU = Verbose|Any CPU Verbose|Any CPU = Verbose|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Mono|Any CPU.Build.0 = Mono|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Release|Any CPU.Build.0 = Release|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Mono|Any CPU.Build.0 = Mono|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Release|Any CPU.Build.0 = Release|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
{6756F911-BD09-4226-B597-67871DEB8ED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6756F911-BD09-4226-B597-67871DEB8ED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6756F911-BD09-4226-B597-67871DEB8ED5}.Debug|Any CPU.Build.0 = Debug|Any CPU {6756F911-BD09-4226-B597-67871DEB8ED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6756F911-BD09-4226-B597-67871DEB8ED5}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU {6756F911-BD09-4226-B597-67871DEB8ED5}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
...@@ -139,16 +119,6 @@ Global ...@@ -139,16 +119,6 @@ Global
{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Release|Any CPU.Build.0 = Release|Any CPU {36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Release|Any CPU.Build.0 = Release|Any CPU
{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Verbose|Any CPU.ActiveCfg = Release|Any CPU {36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Verbose|Any CPU.ActiveCfg = Release|Any CPU
{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Verbose|Any CPU.Build.0 = Release|Any CPU {36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}.Verbose|Any CPU.Build.0 = Release|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Mono|Any CPU.Build.0 = Mono|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Release|Any CPU.Build.0 = Release|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
{75CED009-AAC6-4AC1-9C38-A0530619062D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {75CED009-AAC6-4AC1-9C38-A0530619062D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75CED009-AAC6-4AC1-9C38-A0530619062D}.Debug|Any CPU.Build.0 = Debug|Any CPU {75CED009-AAC6-4AC1-9C38-A0530619062D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75CED009-AAC6-4AC1-9C38-A0530619062D}.Log Output|Any CPU.ActiveCfg = Release|Any CPU {75CED009-AAC6-4AC1-9C38-A0530619062D}.Log Output|Any CPU.ActiveCfg = Release|Any CPU
...@@ -179,6 +149,36 @@ Global ...@@ -179,6 +149,36 @@ Global
{8CE5D027-E332-42DD-BA54-16310DCD529C}.Release|Any CPU.Build.0 = Release|Any CPU {8CE5D027-E332-42DD-BA54-16310DCD529C}.Release|Any CPU.Build.0 = Release|Any CPU
{8CE5D027-E332-42DD-BA54-16310DCD529C}.Verbose|Any CPU.ActiveCfg = Mono|Any CPU {8CE5D027-E332-42DD-BA54-16310DCD529C}.Verbose|Any CPU.ActiveCfg = Mono|Any CPU
{8CE5D027-E332-42DD-BA54-16310DCD529C}.Verbose|Any CPU.Build.0 = Mono|Any CPU {8CE5D027-E332-42DD-BA54-16310DCD529C}.Verbose|Any CPU.Build.0 = Mono|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Mono|Any CPU.Build.0 = Mono|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Release|Any CPU.Build.0 = Release|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{7CEC07F2-8C03-4C42-B048-738B215824C1}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Mono|Any CPU.Build.0 = Mono|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Release|Any CPU.Build.0 = Release|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{EBF46088-E318-4D32-9EFB-01EF130A4554}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Log Output|Any CPU.ActiveCfg = Log Output|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Log Output|Any CPU.Build.0 = Log Output|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Mono|Any CPU.ActiveCfg = Mono|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Mono|Any CPU.Build.0 = Mono|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Release|Any CPU.Build.0 = Release|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Verbose|Any CPU.ActiveCfg = Verbose|Any CPU
{19C00111-1328-4089-8565-94920B5B47F2}.Verbose|Any CPU.Build.0 = Verbose|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{8EA21FC8-9CF7-438B-94F2-42E3810C3641}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>StackExchange.Redis.md</RootNamespace>
<AssemblyName>StackExchange.Redis.md</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;MONO</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>MONO</DefineConstants>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StackExchange\Redis\Aggregate.cs" />
<Compile Include="StackExchange\Redis\Bitwise.cs" />
<Compile Include="StackExchange\Redis\ClientFlags.cs" />
<Compile Include="StackExchange\Redis\ClientInfo.cs" />
<Compile Include="StackExchange\Redis\ClusterConfiguration.cs" />
<Compile Include="StackExchange\Redis\CommandFlags.cs" />
<Compile Include="StackExchange\Redis\CommandMap.cs" />
<Compile Include="StackExchange\Redis\CommandTrace.cs" />
<Compile Include="StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="StackExchange\Redis\CompletionManager.cs" />
<Compile Include="StackExchange\Redis\Condition.cs" />
<Compile Include="StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs" />
<Compile Include="StackExchange\Redis\ConnectionType.cs" />
<Compile Include="StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="StackExchange\Redis\Exclude.cs" />
<Compile Include="StackExchange\Redis\ExportOptions.cs" />
<Compile Include="StackExchange\Redis\Format.cs" />
<Compile Include="StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="StackExchange\Redis\IBatch.cs" />
<Compile Include="StackExchange\Redis\ICompletable.cs" />
<Compile Include="StackExchange\Redis\IDatabase.cs" />
<Compile Include="StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\IRedis.cs" />
<Compile Include="StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="StackExchange\Redis\IServer.cs" />
<Compile Include="StackExchange\Redis\ISubscriber.cs" />
<Compile Include="StackExchange\Redis\ITransaction.cs" />
<Compile Include="StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="StackExchange\Redis\Message.cs" />
<Compile Include="StackExchange\Redis\MessageCompletable.cs" />
<Compile Include="StackExchange\Redis\MessageQueue.cs" />
<Compile Include="StackExchange\Redis\Order.cs" />
<Compile Include="StackExchange\Redis\PhysicalBridge.cs" />
<Compile Include="StackExchange\Redis\PhysicalConnection.cs" />
<Compile Include="StackExchange\Redis\RawResult.cs" />
<Compile Include="StackExchange\Redis\RedisBase.cs" />
<Compile Include="StackExchange\Redis\RedisBatch.cs" />
<Compile Include="StackExchange\Redis\RedisChannel.cs" />
<Compile Include="StackExchange\Redis\RedisCommand.cs" />
<Compile Include="StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="StackExchange\Redis\RedisKey.cs" />
<Compile Include="StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="StackExchange\Redis\RedisResult.cs" />
<Compile Include="StackExchange\Redis\RedisServer.cs" />
<Compile Include="StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="StackExchange\Redis\RedisType.cs" />
<Compile Include="StackExchange\Redis\RedisValue.cs" />
<Compile Include="StackExchange\Redis\ReplicationChangeOptions.cs" />
<Compile Include="StackExchange\Redis\ResultBox.cs" />
<Compile Include="StackExchange\Redis\ResultProcessor.cs" />
<Compile Include="StackExchange\Redis\ResultType.cs" />
<Compile Include="StackExchange\Redis\SaveType.cs" />
<Compile Include="StackExchange\Redis\ServerCounters.cs" />
<Compile Include="StackExchange\Redis\ServerEndPoint.cs" />
<Compile Include="StackExchange\Redis\ServerSelectionStrategy.cs" />
<Compile Include="StackExchange\Redis\ServerType.cs" />
<Compile Include="StackExchange\Redis\SetOperation.cs" />
<Compile Include="StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="StackExchange\Redis\SocketManager.cs" />
<Compile Include="StackExchange\Redis\SortType.cs" />
<Compile Include="StackExchange\Redis\StringSplits.cs" />
<Compile Include="StackExchange\Redis\TaskSource.cs" />
<Compile Include="StackExchange\Redis\When.cs" />
<Compile Include="StackExchange\Redis\HashEntry.cs" />
<Compile Include="StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="StackExchange\Redis\SocketManager.NoPoll.cs" />
<Compile Include="StackExchange\Redis\SocketManager.Poll.cs" />
<Compile Include="StackExchange\Redis\SortedSetEntry.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.IO.Compression" />
</ItemGroup>
<ItemGroup>
<Folder Include="StackExchange\Redis\" />
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>86526b5c-1163-4481-a5e2-a303a0bb1535</ProjectGuid> <ProjectGuid>ef84877f-59be-41be-9013-e765af0bb72e</ProjectGuid>
<RootNamespace>StackExchange.Redis</RootNamespace> <RootNamespace>StackExchange.Redis</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath> <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath> <OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>
\ No newline at end of file
...@@ -172,6 +172,7 @@ public sealed class ClusterConfiguration ...@@ -172,6 +172,7 @@ public sealed class ClusterConfiguration
private readonly ServerSelectionStrategy serverSelectionStrategy; private readonly ServerSelectionStrategy serverSelectionStrategy;
internal ClusterConfiguration(ServerSelectionStrategy serverSelectionStrategy, string nodes, EndPoint origin) internal ClusterConfiguration(ServerSelectionStrategy serverSelectionStrategy, string nodes, EndPoint origin)
{ {
// Beware: Any exception thrown here will wreak silent havoc like inability to connect to cluster nodes or non returning calls
this.serverSelectionStrategy = serverSelectionStrategy; this.serverSelectionStrategy = serverSelectionStrategy;
this.origin = origin; this.origin = origin;
using (var reader = new StringReader(nodes)) using (var reader = new StringReader(nodes))
...@@ -180,9 +181,36 @@ internal ClusterConfiguration(ServerSelectionStrategy serverSelectionStrategy, s ...@@ -180,9 +181,36 @@ internal ClusterConfiguration(ServerSelectionStrategy serverSelectionStrategy, s
while ((line = reader.ReadLine()) != null) while ((line = reader.ReadLine()) != null)
{ {
if (string.IsNullOrWhiteSpace(line)) continue; if (string.IsNullOrWhiteSpace(line)) continue;
var node = new ClusterNode(this, line, origin); var node = new ClusterNode(this, line, origin);
nodeLookup.Add(node.EndPoint, node); // Be resilient to ":0 {master,slave},fail,noaddr" nodes
if (node.IsNoAddr)
continue;
if (nodeLookup.ContainsKey(node.EndPoint))
{
// Deal with conflicting node entries for the same endpoint
// This can happen in dynamic environments when a node goes down and a new one is created
// to replace it.
if (!node.IsConnected)
{
// The node we're trying to add is probably about to become stale. Ignore it.
continue;
}
else if (!nodeLookup[node.EndPoint].IsConnected)
{
// The node we registered previously is probably stale. Replace it with a known good node.
nodeLookup[node.EndPoint] = node;
}
else
{
// We have conflicting connected nodes. There's nothing much we can do other than
// wait for the cluster state to converge and refresh on the next pass.
// The same is true if we have multiple disconnected nodes.
}
}
else
{
nodeLookup.Add(node.EndPoint, node);
}
} }
} }
} }
...@@ -262,6 +290,10 @@ public sealed class ClusterNode : IEquatable<ClusterNode>, IComparable<ClusterN ...@@ -262,6 +290,10 @@ public sealed class ClusterNode : IEquatable<ClusterNode>, IComparable<ClusterN
private readonly bool isSlave; private readonly bool isSlave;
private readonly bool isNoAddr;
private readonly bool isConnected;
private readonly string nodeId, parentNodeId, raw; private readonly string nodeId, parentNodeId, raw;
private readonly IList<SlotRange> slots; private readonly IList<SlotRange> slots;
...@@ -275,22 +307,18 @@ public sealed class ClusterNode : IEquatable<ClusterNode>, IComparable<ClusterN ...@@ -275,22 +307,18 @@ public sealed class ClusterNode : IEquatable<ClusterNode>, IComparable<ClusterN
internal ClusterNode() { } internal ClusterNode() { }
internal ClusterNode(ClusterConfiguration configuration, string raw, EndPoint origin) internal ClusterNode(ClusterConfiguration configuration, string raw, EndPoint origin)
{ {
// http://redis.io/commands/cluster-nodes
this.configuration = configuration; this.configuration = configuration;
this.raw = raw; this.raw = raw;
var parts = raw.Split(StringSplits.Space); var parts = raw.Split(StringSplits.Space);
var flags = parts[2].Split(StringSplits.Comma); var flags = parts[2].Split(StringSplits.Comma);
if (flags.Contains("myself")) endpoint = Format.TryParseEndPoint(parts[1]);
{
endpoint = origin;
}
else
{
endpoint = Format.TryParseEndPoint(parts[1]);
}
nodeId = parts[0]; nodeId = parts[0];
isSlave = flags.Contains("slave"); isSlave = flags.Contains("slave");
isNoAddr = flags.Contains("noaddr");
parentNodeId = string.IsNullOrWhiteSpace(parts[3]) ? null : parts[3]; parentNodeId = string.IsNullOrWhiteSpace(parts[3]) ? null : parts[3];
List<SlotRange> slots = null; List<SlotRange> slots = null;
...@@ -305,6 +333,7 @@ internal ClusterNode(ClusterConfiguration configuration, string raw, EndPoint or ...@@ -305,6 +333,7 @@ internal ClusterNode(ClusterConfiguration configuration, string raw, EndPoint or
} }
} }
this.slots = slots == null ? NoSlots : slots.AsReadOnly(); this.slots = slots == null ? NoSlots : slots.AsReadOnly();
this.isConnected = parts[7] == "connected"; // Can be "connected" or "disconnected"
} }
/// <summary> /// <summary>
/// Gets all child nodes of the current node /// Gets all child nodes of the current node
...@@ -339,6 +368,16 @@ public IList<ClusterNode> Children ...@@ -339,6 +368,16 @@ public IList<ClusterNode> Children
/// </summary> /// </summary>
public bool IsSlave { get { return isSlave; } } public bool IsSlave { get { return isSlave; } }
/// <summary>
/// Gets whether this node is flagged as noaddr
/// </summary>
public bool IsNoAddr { get { return isNoAddr; } }
/// <summary>
/// Gets the node's connection status
/// </summary>
public bool IsConnected { get { return isConnected; } }
/// <summary> /// <summary>
/// Gets the unique node-id of the current node /// Gets the unique node-id of the current node
/// </summary> /// </summary>
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
/// <summary> /// <summary>
/// Represents the commands mapped on a particular configuration /// Represents the commands mapped on a particular configuration
/// </summary> /// </summary>
public sealed class CommandMap public sealed class CommandMap
{ {
private static readonly CommandMap private static readonly CommandMap
@default = CreateImpl(null, null), @default = CreateImpl(null, null),
twemproxy = CreateImpl(null, exclusions: new HashSet<RedisCommand> twemproxy = CreateImpl(null, exclusions: new HashSet<RedisCommand>
{ {
// see https://github.com/twitter/twemproxy/blob/master/notes/redis.md // see https://github.com/twitter/twemproxy/blob/master/notes/redis.md
RedisCommand.KEYS, RedisCommand.MIGRATE, RedisCommand.MOVE, RedisCommand.OBJECT, RedisCommand.RANDOMKEY, RedisCommand.KEYS, RedisCommand.MIGRATE, RedisCommand.MOVE, RedisCommand.OBJECT, RedisCommand.RANDOMKEY,
RedisCommand.RENAME, RedisCommand.RENAMENX, RedisCommand.SORT, RedisCommand.SCAN, RedisCommand.RENAME, RedisCommand.RENAMENX, RedisCommand.SORT, RedisCommand.SCAN,
RedisCommand.BITOP, RedisCommand.MSET, RedisCommand.MSETNX, RedisCommand.BITOP, RedisCommand.MSET, RedisCommand.MSETNX,
RedisCommand.HSCAN, RedisCommand.HSCAN,
RedisCommand.BLPOP, RedisCommand.BRPOP, RedisCommand.BRPOPLPUSH, // yeah, me neither! RedisCommand.BLPOP, RedisCommand.BRPOP, RedisCommand.BRPOPLPUSH, // yeah, me neither!
RedisCommand.SSCAN, RedisCommand.SSCAN,
RedisCommand.ZSCAN, RedisCommand.ZSCAN,
RedisCommand.PSUBSCRIBE, RedisCommand.PUBLISH, RedisCommand.PUNSUBSCRIBE, RedisCommand.SUBSCRIBE, RedisCommand.UNSUBSCRIBE, RedisCommand.PSUBSCRIBE, RedisCommand.PUBLISH, RedisCommand.PUNSUBSCRIBE, RedisCommand.SUBSCRIBE, RedisCommand.UNSUBSCRIBE,
RedisCommand.DISCARD, RedisCommand.EXEC, RedisCommand.MULTI, RedisCommand.UNWATCH, RedisCommand.WATCH, RedisCommand.DISCARD, RedisCommand.EXEC, RedisCommand.MULTI, RedisCommand.UNWATCH, RedisCommand.WATCH,
RedisCommand.SCRIPT, RedisCommand.SCRIPT,
RedisCommand.AUTH, RedisCommand.ECHO, RedisCommand.PING, RedisCommand.QUIT, RedisCommand.SELECT, RedisCommand.ECHO, RedisCommand.PING, RedisCommand.QUIT, RedisCommand.SELECT,
RedisCommand.BGREWRITEAOF, RedisCommand.BGSAVE, RedisCommand.CLIENT, RedisCommand.CLUSTER, RedisCommand.CONFIG, RedisCommand.DBSIZE, RedisCommand.BGREWRITEAOF, RedisCommand.BGSAVE, RedisCommand.CLIENT, RedisCommand.CLUSTER, RedisCommand.CONFIG, RedisCommand.DBSIZE,
RedisCommand.DEBUG, RedisCommand.FLUSHALL, RedisCommand.FLUSHDB, RedisCommand.INFO, RedisCommand.LASTSAVE, RedisCommand.MONITOR, RedisCommand.SAVE, RedisCommand.DEBUG, RedisCommand.FLUSHALL, RedisCommand.FLUSHDB, RedisCommand.INFO, RedisCommand.LASTSAVE, RedisCommand.MONITOR, RedisCommand.SAVE,
RedisCommand.SHUTDOWN, RedisCommand.SLAVEOF, RedisCommand.SLOWLOG, RedisCommand.SYNC, RedisCommand.TIME RedisCommand.SHUTDOWN, RedisCommand.SLAVEOF, RedisCommand.SLOWLOG, RedisCommand.SYNC, RedisCommand.TIME
}), ssdb = Create(new HashSet<string> { }), ssdb = Create(new HashSet<string> {
// see http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html // see http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html
"ping", "ping",
"get", "set", "del", "incr", "incrby", "mget", "mset", "keys", "getset", "setnx", "get", "set", "del", "incr", "incrby", "mget", "mset", "keys", "getset", "setnx",
"hget", "hset", "hdel", "hincrby", "hkeys", "hvals", "hmget", "hmset", "hlen", "hget", "hset", "hdel", "hincrby", "hkeys", "hvals", "hmget", "hmset", "hlen",
"zscore", "zadd", "zrem", "zrange", "zrangebyscore", "zincrby", "zdecrby", "zcard", "zscore", "zadd", "zrem", "zrange", "zrangebyscore", "zincrby", "zdecrby", "zcard",
"llen", "lpush", "rpush", "lpop", "rpop", "lrange", "lindex" "llen", "lpush", "rpush", "lpop", "rpop", "lrange", "lindex"
}, true), }, true),
sentinel = Create(new HashSet<string> { sentinel = Create(new HashSet<string> {
// see http://redis.io/topics/sentinel // see http://redis.io/topics/sentinel
"ping", "info", "sentinel", "subscribe", "psubscribe", "unsubscribe", "punsubscribe" }, true); "ping", "info", "sentinel", "subscribe", "psubscribe", "unsubscribe", "punsubscribe" }, true);
private readonly byte[][] map; private readonly byte[][] map;
internal CommandMap(byte[][] map) internal CommandMap(byte[][] map)
{ {
this.map = map; this.map = map;
} }
/// <summary> /// <summary>
/// The default commands specified by redis /// The default commands specified by redis
/// </summary> /// </summary>
public static CommandMap Default { get { return @default; } } public static CommandMap Default { get { return @default; } }
/// <summary> /// <summary>
/// The commands available to <a href="twemproxy">https://github.com/twitter/twemproxy</a> /// The commands available to <a href="twemproxy">https://github.com/twitter/twemproxy</a>
/// </summary> /// </summary>
/// <remarks>https://github.com/twitter/twemproxy/blob/master/notes/redis.md</remarks> /// <remarks>https://github.com/twitter/twemproxy/blob/master/notes/redis.md</remarks>
public static CommandMap Twemproxy { get { return twemproxy; } } public static CommandMap Twemproxy { get { return twemproxy; } }
/// <summary> /// <summary>
/// The commands available to <a href="ssdb">http://www.ideawu.com/ssdb/</a> /// The commands available to <a href="ssdb">http://www.ideawu.com/ssdb/</a>
/// </summary> /// </summary>
/// <remarks>http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html</remarks> /// <remarks>http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html</remarks>
public static CommandMap SSDB { get { return ssdb; } } public static CommandMap SSDB { get { return ssdb; } }
/// <summary> /// <summary>
/// The commands available to <a href="Sentinel">http://redis.io/topics/sentinel</a> /// The commands available to <a href="Sentinel">http://redis.io/topics/sentinel</a>
/// </summary> /// </summary>
/// <remarks>http://redis.io/topics/sentinel</remarks> /// <remarks>http://redis.io/topics/sentinel</remarks>
public static CommandMap Sentinel { get { return sentinel; } } public static CommandMap Sentinel { get { return sentinel; } }
/// <summary> /// <summary>
/// Create a new CommandMap, customizing some commands /// Create a new CommandMap, customizing some commands
/// </summary> /// </summary>
public static CommandMap Create(Dictionary<string, string> overrides) public static CommandMap Create(Dictionary<string, string> overrides)
{ {
if (overrides == null || overrides.Count == 0) return Default; if (overrides == null || overrides.Count == 0) return Default;
if (ReferenceEquals(overrides.Comparer, StringComparer.OrdinalIgnoreCase)) if (ReferenceEquals(overrides.Comparer, StringComparer.OrdinalIgnoreCase))
{ {
// that's ok; we're happy with ordinal/invariant case-insensitive // that's ok; we're happy with ordinal/invariant case-insensitive
// (but not culture-specific insensitive; completely untested) // (but not culture-specific insensitive; completely untested)
} }
else else
{ {
// need case insensitive // need case insensitive
overrides = new Dictionary<string, string>(overrides, StringComparer.OrdinalIgnoreCase); overrides = new Dictionary<string, string>(overrides, StringComparer.OrdinalIgnoreCase);
} }
return CreateImpl(overrides, null); return CreateImpl(overrides, null);
} }
/// <summary> /// <summary>
/// Creates a CommandMap by specifying which commands are available or unavailable /// Creates a CommandMap by specifying which commands are available or unavailable
/// </summary> /// </summary>
public static CommandMap Create(HashSet<string> commands, bool available = true) public static CommandMap Create(HashSet<string> commands, bool available = true)
{ {
if (available) if (available)
{ {
var dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); var dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
// nix everything // nix everything
foreach (RedisCommand command in Enum.GetValues(typeof(RedisCommand))) foreach (RedisCommand command in Enum.GetValues(typeof(RedisCommand)))
{ {
dictionary[command.ToString()] = null; dictionary[command.ToString()] = null;
} }
if (commands != null) if (commands != null)
{ {
// then include (by removal) the things that are available // then include (by removal) the things that are available
foreach (string command in commands) foreach (string command in commands)
{ {
dictionary.Remove(command); dictionary.Remove(command);
} }
} }
return CreateImpl(dictionary, null); return CreateImpl(dictionary, null);
} }
else else
{ {
HashSet<RedisCommand> exclusions = null; HashSet<RedisCommand> exclusions = null;
if (commands != null) if (commands != null)
{ {
// nix the things that are specified // nix the things that are specified
foreach (var command in commands) foreach (var command in commands)
{ {
RedisCommand parsed; RedisCommand parsed;
if (Enum.TryParse(command, true, out parsed)) if (Enum.TryParse(command, true, out parsed))
{ {
(exclusions ?? (exclusions = new HashSet<RedisCommand>())).Add(parsed); (exclusions ?? (exclusions = new HashSet<RedisCommand>())).Add(parsed);
} }
} }
} }
if (exclusions == null || exclusions.Count == 0) return Default; if (exclusions == null || exclusions.Count == 0) return Default;
return CreateImpl(null, exclusions); return CreateImpl(null, exclusions);
} }
} }
/// <summary> /// <summary>
/// See Object.ToString() /// See Object.ToString()
/// </summary> /// </summary>
public override string ToString() public override string ToString()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
AppendDeltas(sb); AppendDeltas(sb);
return sb.ToString(); return sb.ToString();
} }
internal void AppendDeltas(StringBuilder sb) internal void AppendDeltas(StringBuilder sb)
{ {
for (int i = 0; i < map.Length; i++) for (int i = 0; i < map.Length; i++)
{ {
var key = ((RedisCommand)i).ToString(); var key = ((RedisCommand)i).ToString();
var value = map[i] == null ? "" : Encoding.UTF8.GetString(map[i]); var value = map[i] == null ? "" : Encoding.UTF8.GetString(map[i]);
if (key != value) if (key != value)
{ {
if (sb.Length != 0) sb.Append(','); if (sb.Length != 0) sb.Append(',');
sb.Append('$').Append(key).Append('=').Append(value); sb.Append('$').Append(key).Append('=').Append(value);
} }
} }
} }
internal void AssertAvailable(RedisCommand command) internal void AssertAvailable(RedisCommand command)
{ {
if (map[(int)command] == null) throw ExceptionFactory.CommandDisabled(false, command, null, null); if (map[(int)command] == null) throw ExceptionFactory.CommandDisabled(false, command, null, null);
} }
internal byte[] GetBytes(RedisCommand command) internal byte[] GetBytes(RedisCommand command)
{ {
return map[(int)command]; return map[(int)command];
} }
internal bool IsAvailable(RedisCommand command) internal bool IsAvailable(RedisCommand command)
{ {
return map[(int)command] != null; return map[(int)command] != null;
} }
private static CommandMap CreateImpl(Dictionary<string, string> caseInsensitiveOverrides, HashSet<RedisCommand> exclusions) private static CommandMap CreateImpl(Dictionary<string, string> caseInsensitiveOverrides, HashSet<RedisCommand> exclusions)
{ {
var commands = (RedisCommand[])Enum.GetValues(typeof(RedisCommand)); var commands = (RedisCommand[])Enum.GetValues(typeof(RedisCommand));
byte[][] map = new byte[commands.Length][]; byte[][] map = new byte[commands.Length][];
bool haveDelta = false; bool haveDelta = false;
for (int i = 0; i < commands.Length; i++) for (int i = 0; i < commands.Length; i++)
{ {
int idx = (int)commands[i]; int idx = (int)commands[i];
string name = commands[i].ToString(), value = name; string name = commands[i].ToString(), value = name;
if (exclusions != null && exclusions.Contains(commands[i])) if (exclusions != null && exclusions.Contains(commands[i]))
{ {
map[idx] = null; map[idx] = null;
} }
else else
{ {
if (caseInsensitiveOverrides != null) if (caseInsensitiveOverrides != null)
{ {
string tmp; string tmp;
if (caseInsensitiveOverrides.TryGetValue(name, out tmp)) if (caseInsensitiveOverrides.TryGetValue(name, out tmp))
{ {
value = tmp; value = tmp;
} }
} }
if (value != name) haveDelta = true; if (value != name) haveDelta = true;
haveDelta = true; haveDelta = true;
byte[] val = string.IsNullOrWhiteSpace(value) ? null : Encoding.UTF8.GetBytes(value); byte[] val = string.IsNullOrWhiteSpace(value) ? null : Encoding.UTF8.GetBytes(value);
map[idx] = val; map[idx] = val;
} }
} }
if (!haveDelta && @default != null) return @default; if (!haveDelta && @default != null) return @default;
return new CommandMap(map); return new CommandMap(map);
} }
} }
} }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackExchange.Redis
{
/// <summary>
/// Helper for Array.ConvertAll() as it's missing on .Net Core.
/// </summary>
public static class ConvertHelper
{
/// <summary>
/// Converts array of one type to an array of another type.
/// </summary>
/// <typeparam name="TInput">Input type</typeparam>
/// <typeparam name="TOutput">Output type</typeparam>
/// <param name="source">source</param>
/// <param name="selector">selector</param>
/// <returns></returns>
public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] source, Func<TInput, TOutput> selector)
{
#if CORE_CLR
TOutput[] arr = new TOutput[source.Length];
for(int i = 0 ; i < arr.Length ; i++)
arr[i] = selector(source[i]);
return arr;
#else
return Array.ConvertAll(source, item => selector(item));
#endif
}
}
}
...@@ -10,7 +10,7 @@ internal static class VolatileWrapper ...@@ -10,7 +10,7 @@ internal static class VolatileWrapper
{ {
public static int Read(ref int location) public static int Read(ref int location)
{ {
#if !DNXCORE50 #if !CORE_CLR
return System.Threading.Thread.VolatileRead(ref location); return System.Threading.Thread.VolatileRead(ref location);
#else #else
return System.Threading.Volatile.Read(ref location); return System.Threading.Volatile.Read(ref location);
...@@ -19,7 +19,7 @@ public static int Read(ref int location) ...@@ -19,7 +19,7 @@ public static int Read(ref int location)
public static void Write(ref int address, int value) public static void Write(ref int address, int value)
{ {
#if !DNXCORE50 #if !CORE_CLR
System.Threading.Thread.VolatileWrite(ref address, value); System.Threading.Thread.VolatileWrite(ref address, value);
#else #else
System.Threading.Volatile.Write(ref address, value); System.Threading.Volatile.Write(ref address, value);
......
...@@ -30,7 +30,7 @@ public enum Proxy ...@@ -30,7 +30,7 @@ public enum Proxy
/// The options relevant to a set of redis connections /// The options relevant to a set of redis connections
/// </summary> /// </summary>
public sealed class ConfigurationOptions public sealed class ConfigurationOptions
#if !DNXCORE50 #if !CORE_CLR
: ICloneable : ICloneable
#endif #endif
{ {
...@@ -143,7 +143,7 @@ public static string TryNormalize(string value) ...@@ -143,7 +143,7 @@ public static string TryNormalize(string value)
/// Indicates whether the connection should be encrypted /// Indicates whether the connection should be encrypted
/// </summary> /// </summary>
[Obsolete("Please use .Ssl instead of .UseSsl"), [Obsolete("Please use .Ssl instead of .UseSsl"),
#if !DNXCORE50 #if !CORE_CLR
Browsable(false), Browsable(false),
#endif #endif
EditorBrowsable(EditorBrowsableState.Never)] EditorBrowsable(EditorBrowsableState.Never)]
...@@ -470,7 +470,7 @@ static void Append(StringBuilder sb, string prefix, object value) ...@@ -470,7 +470,7 @@ static void Append(StringBuilder sb, string prefix, object value)
} }
} }
#if !DNXCORE50 #if !CORE_CLR
static bool IsOption(string option, string prefix) static bool IsOption(string option, string prefix)
{ {
return option.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase); return option.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase);
...@@ -492,7 +492,7 @@ void Clear() ...@@ -492,7 +492,7 @@ void Clear()
SocketManager = null; SocketManager = null;
} }
#if !DNXCORE50 #if !CORE_CLR
object ICloneable.Clone() { return Clone(); } object ICloneable.Clone() { return Clone(); }
#endif #endif
......
...@@ -482,7 +482,7 @@ public EndPoint[] GetEndPoints(bool configuredOnly = false) ...@@ -482,7 +482,7 @@ public EndPoint[] GetEndPoints(bool configuredOnly = false)
{ {
if (configuredOnly) return configuration.EndPoints.ToArray(); if (configuredOnly) return configuration.EndPoints.ToArray();
return serverSnapshot.Select(x => x.EndPoint).ToArray(); return ConvertHelper.ConvertAll(serverSnapshot, x => x.EndPoint);
} }
private readonly int timeoutMilliseconds; private readonly int timeoutMilliseconds;
...@@ -561,7 +561,7 @@ private static bool WaitAllIgnoreErrors(Task[] tasks, int timeout) ...@@ -561,7 +561,7 @@ private static bool WaitAllIgnoreErrors(Task[] tasks, int timeout)
return false; return false;
} }
#if !DNXCORE50 #if !CORE_CLR
private void LogLockedWithThreadPoolStats(TextWriter log, string message, out int busyWorkerCount) private void LogLockedWithThreadPoolStats(TextWriter log, string message, out int busyWorkerCount)
{ {
busyWorkerCount = 0; busyWorkerCount = 0;
...@@ -603,7 +603,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli ...@@ -603,7 +603,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
} }
var watch = Stopwatch.StartNew(); var watch = Stopwatch.StartNew();
#if !DNXCORE50 #if !CORE_CLR
int busyWorkerCount; int busyWorkerCount;
LogLockedWithThreadPoolStats(log, "Awaiting task completion", out busyWorkerCount); LogLockedWithThreadPoolStats(log, "Awaiting task completion", out busyWorkerCount);
#endif #endif
...@@ -613,7 +613,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli ...@@ -613,7 +613,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds); var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds);
if (remaining <= 0) if (remaining <= 0)
{ {
#if !DNXCORE50 #if !CORE_CLR
LogLockedWithThreadPoolStats(log, "Timeout before awaiting for tasks", out busyWorkerCount); LogLockedWithThreadPoolStats(log, "Timeout before awaiting for tasks", out busyWorkerCount);
#endif #endif
return false; return false;
...@@ -627,7 +627,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli ...@@ -627,7 +627,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
var any = Task.WhenAny(allTasks, Task.Delay(remaining)).ObserveErrors(); var any = Task.WhenAny(allTasks, Task.Delay(remaining)).ObserveErrors();
#endif #endif
bool all = await any.ForAwait() == allTasks; bool all = await any.ForAwait() == allTasks;
#if !DNXCORE50 #if !CORE_CLR
LogLockedWithThreadPoolStats(log, all ? "All tasks completed cleanly" : "Not all tasks completed cleanly", out busyWorkerCount); LogLockedWithThreadPoolStats(log, all ? "All tasks completed cleanly" : "Not all tasks completed cleanly", out busyWorkerCount);
#endif #endif
return all; return all;
...@@ -645,7 +645,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli ...@@ -645,7 +645,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds); var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds);
if (remaining <= 0) if (remaining <= 0)
{ {
#if !DNXCORE50 #if !CORE_CLR
LogLockedWithThreadPoolStats(log, "Timeout awaiting tasks", out busyWorkerCount); LogLockedWithThreadPoolStats(log, "Timeout awaiting tasks", out busyWorkerCount);
#endif #endif
return false; return false;
...@@ -663,7 +663,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli ...@@ -663,7 +663,7 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
{ } { }
} }
} }
#if !DNXCORE50 #if !CORE_CLR
LogLockedWithThreadPoolStats(log, "Finished awaiting tasks", out busyWorkerCount); LogLockedWithThreadPoolStats(log, "Finished awaiting tasks", out busyWorkerCount);
#endif #endif
return false; return false;
...@@ -1216,114 +1216,155 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1216,114 +1216,155 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
} }
const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority; const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority;
var available = new Task<bool>[endpoints.Count]; List<ServerEndPoint> masters = new List<ServerEndPoint>(endpoints.Count);
var servers = new ServerEndPoint[available.Length];
bool useTieBreakers = !string.IsNullOrWhiteSpace(configuration.TieBreaker); bool useTieBreakers = !string.IsNullOrWhiteSpace(configuration.TieBreaker);
var tieBreakers = useTieBreakers ? new Task<string>[endpoints.Count] : null;
RedisKey tieBreakerKey = useTieBreakers ? (RedisKey)configuration.TieBreaker : default(RedisKey); ServerEndPoint[] servers = null;
for (int i = 0; i < available.Length; i++) Task<string>[] tieBreakers = null;
bool encounteredConnectedClusterServer = false;
Stopwatch watch = null;
int iterCount = first ? 2 : 1;
// this is fix for https://github.com/StackExchange/StackExchange.Redis/issues/300
// auto discoverability of cluster nodes is made synchronous.
// we try to connect to endpoints specified inside the user provided configuration
// and when we encounter one such endpoint to which we are able to successfully connect,
// we get the list of cluster nodes from this endpoint and try to proactively connect
// to these nodes instead of relying on auto configure
for (int iter = 0; iter < iterCount; ++iter)
{ {
Trace("Testing: " + Format.ToString(endpoints[i])); if (endpoints == null) break;
var server = GetServerEndPoint(endpoints[i]);
//server.ReportNextFailure(); var available = new Task<bool>[endpoints.Count];
servers[i] = server; tieBreakers = useTieBreakers ? new Task<string>[endpoints.Count] : null;
if (reconfigureAll && server.IsConnected) servers = new ServerEndPoint[available.Length];
RedisKey tieBreakerKey = useTieBreakers ? (RedisKey)configuration.TieBreaker : default(RedisKey);
for (int i = 0; i < available.Length; i++)
{ {
LogLocked(log, "Refreshing {0}...", Format.ToString(server.EndPoint)); Trace("Testing: " + Format.ToString(endpoints[i]));
// note that these will be processed synchronously *BEFORE* the tracer is processed, var server = GetServerEndPoint(endpoints[i]);
// so we know that the configuration will be up to date if we see the tracer //server.ReportNextFailure();
server.AutoConfigure(null); servers[i] = server;
} if (reconfigureAll && server.IsConnected)
available[i] = server.SendTracer(log); {
if (useTieBreakers) LogLocked(log, "Refreshing {0}...", Format.ToString(server.EndPoint));
{ // note that these will be processed synchronously *BEFORE* the tracer is processed,
LogLocked(log, "Requesting tie-break from {0} > {1}...", Format.ToString(server.EndPoint), configuration.TieBreaker); // so we know that the configuration will be up to date if we see the tracer
Message msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey); server.AutoConfigure(null);
msg.SetInternalCall(); }
msg = LoggingMessage.Create(log, msg); available[i] = server.SendTracer(log);
tieBreakers[i] = server.QueueDirectAsync(msg, ResultProcessor.String); if (useTieBreakers)
{
LogLocked(log, "Requesting tie-break from {0} > {1}...", Format.ToString(server.EndPoint), configuration.TieBreaker);
Message msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey);
msg.SetInternalCall();
msg = LoggingMessage.Create(log, msg);
tieBreakers[i] = server.QueueDirectAsync(msg, ResultProcessor.String);
}
} }
}
LogLocked(log, "Allowing endpoints {0} to respond...", TimeSpan.FromMilliseconds(configuration.ConnectTimeout)); watch = watch ?? Stopwatch.StartNew();
Trace("Allowing endpoints " + TimeSpan.FromMilliseconds(configuration.ConnectTimeout) + " to respond..."); var remaining = configuration.ConnectTimeout - checked((int)watch.ElapsedMilliseconds);
await WaitAllIgnoreErrorsAsync(available, configuration.ConnectTimeout, log).ForAwait(); LogLocked(log, "Allowing endpoints {0} to respond...", TimeSpan.FromMilliseconds(remaining));
List<ServerEndPoint> masters = new List<ServerEndPoint>(available.Length); Trace("Allowing endpoints " + TimeSpan.FromMilliseconds(remaining) + " to respond...");
await WaitAllIgnoreErrorsAsync(available, remaining, log).ForAwait();
for (int i = 0; i < available.Length; i++) EndPointCollection updatedClusterEndpointCollection = null;
{ for (int i = 0; i < available.Length; i++)
var task = available[i];
Trace(Format.ToString(endpoints[i]) + ": " + task.Status);
if (task.IsFaulted)
{ {
servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); var task = available[i];
var aex = task.Exception; Trace(Format.ToString(endpoints[i]) + ": " + task.Status);
foreach (var ex in aex.InnerExceptions) if (task.IsFaulted)
{
servers[i].SetUnselectable(UnselectableFlags.DidNotRespond);
var aex = task.Exception;
foreach (var ex in aex.InnerExceptions)
{
LogLocked(log, "{0} faulted: {1}", Format.ToString(endpoints[i]), ex.Message);
failureMessage = ex.Message;
}
}
else if (task.IsCanceled)
{ {
LogLocked(log, "{0} faulted: {1}", Format.ToString(endpoints[i]), ex.Message); servers[i].SetUnselectable(UnselectableFlags.DidNotRespond);
failureMessage = ex.Message; LogLocked(log, "{0} was canceled", Format.ToString(endpoints[i]));
} }
} else if (task.IsCompleted)
else if (task.IsCanceled)
{
servers[i].SetUnselectable(UnselectableFlags.DidNotRespond);
LogLocked(log, "{0} was canceled", Format.ToString(endpoints[i]));
}
else if (task.IsCompleted)
{
var server = servers[i];
if (task.Result)
{ {
servers[i].ClearUnselectable(UnselectableFlags.DidNotRespond); var server = servers[i];
LogLocked(log, "{0} returned with success", Format.ToString(endpoints[i])); if (task.Result)
// count the server types
switch (server.ServerType)
{ {
case ServerType.Twemproxy: servers[i].ClearUnselectable(UnselectableFlags.DidNotRespond);
case ServerType.Standalone: LogLocked(log, "{0} returned with success", Format.ToString(endpoints[i]));
standaloneCount++;
break; // count the server types
case ServerType.Sentinel: switch (server.ServerType)
sentinelCount++; {
break; case ServerType.Twemproxy:
case ServerType.Cluster: case ServerType.Standalone:
clusterCount++; standaloneCount++;
break; break;
} case ServerType.Sentinel:
sentinelCount++;
break;
case ServerType.Cluster:
clusterCount++;
break;
}
// set the server UnselectableFlags and update masters list if (clusterCount > 0 && !encounteredConnectedClusterServer)
switch (server.ServerType) {
// we have encountered a connected server with clustertype for the first time.
// so we will get list of other nodes from this server using "CLUSTER NODES" command
// and try to connect to these other nodes in the next iteration
encounteredConnectedClusterServer = true;
updatedClusterEndpointCollection = GetEndpointsFromClusterNodes(server, log);
}
// set the server UnselectableFlags and update masters list
switch (server.ServerType)
{
case ServerType.Twemproxy:
case ServerType.Sentinel:
case ServerType.Standalone:
case ServerType.Cluster:
servers[i].ClearUnselectable(UnselectableFlags.ServerType);
if (server.IsSlave)
{
servers[i].ClearUnselectable(UnselectableFlags.RedundantMaster);
}
else
{
masters.Add(server);
}
break;
default:
servers[i].SetUnselectable(UnselectableFlags.ServerType);
break;
}
}
else
{ {
case ServerType.Twemproxy: servers[i].SetUnselectable(UnselectableFlags.DidNotRespond);
case ServerType.Sentinel: LogLocked(log, "{0} returned, but incorrectly", Format.ToString(endpoints[i]));
case ServerType.Standalone:
case ServerType.Cluster:
servers[i].ClearUnselectable(UnselectableFlags.ServerType);
if (server.IsSlave)
{
servers[i].ClearUnselectable(UnselectableFlags.RedundantMaster);
}
else
{
masters.Add(server);
}
break;
default:
servers[i].SetUnselectable(UnselectableFlags.ServerType);
break;
} }
} }
else else
{ {
servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); servers[i].SetUnselectable(UnselectableFlags.DidNotRespond);
LogLocked(log, "{0} returned, but incorrectly", Format.ToString(endpoints[i])); LogLocked(log, "{0} did not respond", Format.ToString(endpoints[i]));
} }
} }
if (encounteredConnectedClusterServer)
{
endpoints = updatedClusterEndpointCollection;
}
else else
{ {
servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); break; // we do not want to repeat the second iteration
LogLocked(log, "{0} did not respond", Format.ToString(endpoints[i]));
} }
} }
...@@ -1432,6 +1473,23 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1432,6 +1473,23 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
} }
} }
private EndPointCollection GetEndpointsFromClusterNodes(ServerEndPoint server, TextWriter log)
{
var message = Message.Create(-1, CommandFlags.None, RedisCommand.CLUSTER, RedisLiterals.NODES);
ClusterConfiguration clusterConfig = null;
try
{
clusterConfig = this.ExecuteSyncImpl(message, ResultProcessor.ClusterNodes, server);
return new EndPointCollection(clusterConfig.Nodes.Select(node => node.EndPoint).ToList());
}
catch (Exception ex)
{
LogLocked(log, "Encountered error while updating cluster config: " + ex.Message);
return null;
}
}
private void ResetAllNonConnected() private void ResetAllNonConnected()
{ {
var snapshot = serverSnapshot; var snapshot = serverSnapshot;
...@@ -1916,7 +1974,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1916,7 +1974,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
add("Active-Readers", "ar", ar.ToString()); add("Active-Readers", "ar", ar.ToString());
add("Client-Name", "clientName", ClientName); add("Client-Name", "clientName", ClientName);
#if !DNXCORE50 #if !CORE_CLR
string iocp, worker; string iocp, worker;
int busyWorkerCount = GetThreadPoolStats(out iocp, out worker); int busyWorkerCount = GetThreadPoolStats(out iocp, out worker);
add("ThreadPool-IO-Completion", "IOCP", iocp); add("ThreadPool-IO-Completion", "IOCP", iocp);
...@@ -1953,7 +2011,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1953,7 +2011,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
} }
} }
#if !DNXCORE50 #if !CORE_CLR
private static int GetThreadPoolStats(out string iocp, out string worker) private static int GetThreadPoolStats(out string iocp, out string worker)
{ {
//BusyThreads = TP.GetMaxThreads() –TP.GetAVailable(); //BusyThreads = TP.GetMaxThreads() –TP.GetAVailable();
......
...@@ -299,9 +299,10 @@ public enum CompletionType ...@@ -299,9 +299,10 @@ public enum CompletionType
/// </summary> /// </summary>
Async = 2 Async = 2
} }
#if !CORE_CLR
internal class CompletionTypeHelper internal class CompletionTypeHelper
{ {
public static void RunWithCompletionType(Func<AsyncCallback, IAsyncResult> beginAsync, AsyncCallback callback, CompletionType completionType) public static void RunWithCompletionType(Func<AsyncCallback, IAsyncResult> beginAsync, AsyncCallback callback, CompletionType completionType)
{ {
AsyncCallback proxyCallback; AsyncCallback proxyCallback;
...@@ -343,6 +344,7 @@ public static void RunWithCompletionType(Func<AsyncCallback, IAsyncResult> begin ...@@ -343,6 +344,7 @@ public static void RunWithCompletionType(Func<AsyncCallback, IAsyncResult> begin
return; return;
} }
} }
#endif
#if VERBOSE #if VERBOSE
......
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Net; using System.Net;
...@@ -9,6 +10,14 @@ namespace StackExchange.Redis ...@@ -9,6 +10,14 @@ namespace StackExchange.Redis
/// </summary> /// </summary>
public sealed class EndPointCollection : Collection<EndPoint> public sealed class EndPointCollection : Collection<EndPoint>
{ {
public EndPointCollection() : base()
{
}
public EndPointCollection(IList<EndPoint> endpoints) : base(endpoints)
{
}
/// <summary> /// <summary>
/// Format an endpoint /// Format an endpoint
/// </summary> /// </summary>
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace StackExchange.Redis
namespace StackExchange.Redis {
{ /// <summary>
/// <summary> /// Utility methods
/// Utility methods /// </summary>
/// </summary> public static class ExtensionMethods
public static class ExtensionMethods {
{ /// <summary>
/// <summary> /// Create a dictionary from an array of HashEntry values
/// Create a dictionary from an array of HashEntry values /// </summary>
/// </summary> public static Dictionary<string,string> ToStringDictionary(this HashEntry[] hash)
public static Dictionary<string,string> ToStringDictionary(this HashEntry[] hash) {
{ if (hash == null) return null;
if (hash == null) return null;
var result = new Dictionary<string, string>(hash.Length, StringComparer.Ordinal);
var result = new Dictionary<string, string>(hash.Length, StringComparer.Ordinal); for(int i = 0; i < hash.Length; i++)
for(int i = 0; i < hash.Length; i++) {
{ result.Add(hash[i].name, hash[i].value);
result.Add(hash[i].name, hash[i].value); }
} return result;
return result; }
} /// <summary>
/// <summary> /// Create a dictionary from an array of HashEntry values
/// Create a dictionary from an array of HashEntry values /// </summary>
/// </summary> public static Dictionary<RedisValue, RedisValue> ToDictionary(this HashEntry[] hash)
public static Dictionary<RedisValue, RedisValue> ToDictionary(this HashEntry[] hash) {
{ if (hash == null) return null;
if (hash == null) return null;
var result = new Dictionary<RedisValue, RedisValue>(hash.Length);
var result = new Dictionary<RedisValue, RedisValue>(hash.Length); for (int i = 0; i < hash.Length; i++)
for (int i = 0; i < hash.Length; i++) {
{ result.Add(hash[i].name, hash[i].value);
result.Add(hash[i].name, hash[i].value); }
} return result;
return result; }
}
/// <summary>
/// <summary> /// Create a dictionary from an array of SortedSetEntry values
/// Create a dictionary from an array of SortedSetEntry values /// </summary>
/// </summary> public static Dictionary<string, double> ToStringDictionary(this SortedSetEntry[] sortedSet)
public static Dictionary<string, double> ToStringDictionary(this SortedSetEntry[] sortedSet) {
{ if (sortedSet == null) return null;
if (sortedSet == null) return null;
var result = new Dictionary<string, double>(sortedSet.Length, StringComparer.Ordinal);
var result = new Dictionary<string, double>(sortedSet.Length, StringComparer.Ordinal); for (int i = 0; i < sortedSet.Length; i++)
for (int i = 0; i < sortedSet.Length; i++) {
{ result.Add(sortedSet[i].element, sortedSet[i].score);
result.Add(sortedSet[i].element, sortedSet[i].score); }
} return result;
return result; }
}
/// <summary>
/// <summary> /// Create a dictionary from an array of SortedSetEntry values
/// Create a dictionary from an array of SortedSetEntry values /// </summary>
/// </summary> public static Dictionary<RedisValue, double> ToDictionary(this SortedSetEntry[] sortedSet)
public static Dictionary<RedisValue, double> ToDictionary(this SortedSetEntry[] sortedSet) {
{ if (sortedSet == null) return null;
if (sortedSet == null) return null;
var result = new Dictionary<RedisValue, double>(sortedSet.Length);
var result = new Dictionary<RedisValue, double>(sortedSet.Length); for (int i = 0; i < sortedSet.Length; i++)
for (int i = 0; i < sortedSet.Length; i++) {
{ result.Add(sortedSet[i].element, sortedSet[i].score);
result.Add(sortedSet[i].element, sortedSet[i].score); }
} return result;
return result; }
}
/// <summary>
/// <summary> /// Create a dictionary from an array of key/value pairs
/// Create a dictionary from an array of key/value pairs /// </summary>
/// </summary> public static Dictionary<string, string> ToStringDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs)
public static Dictionary<string, string> ToStringDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs) {
{ if (pairs == null) return null;
if (pairs == null) return null;
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal);
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal); for (int i = 0; i < pairs.Length; i++)
for (int i = 0; i < pairs.Length; i++) {
{ result.Add(pairs[i].Key, pairs[i].Value);
result.Add(pairs[i].Key, pairs[i].Value); }
} return result;
return result; }
}
/// <summary>
/// <summary> /// Create a dictionary from an array of key/value pairs
/// Create a dictionary from an array of key/value pairs /// </summary>
/// </summary> public static Dictionary<RedisKey, RedisValue> ToDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs)
public static Dictionary<RedisKey, RedisValue> ToDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs) {
{ if (pairs == null) return null;
if (pairs == null) return null;
var result = new Dictionary<RedisKey, RedisValue>(pairs.Length);
var result = new Dictionary<RedisKey, RedisValue>(pairs.Length); for (int i = 0; i < pairs.Length; i++)
for (int i = 0; i < pairs.Length; i++) {
{ result.Add(pairs[i].Key, pairs[i].Value);
result.Add(pairs[i].Key, pairs[i].Value); }
} return result;
return result; }
}
/// <summary>
/// <summary> /// Create a dictionary from an array of string pairs
/// Create a dictionary from an array of string pairs /// </summary>
/// </summary> public static Dictionary<string, string> ToDictionary(this KeyValuePair<string, string>[] pairs)
public static Dictionary<string, string> ToDictionary(this KeyValuePair<string, string>[] pairs) {
{ if (pairs == null) return null;
if (pairs == null) return null;
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal);
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal); for (int i = 0; i < pairs.Length; i++)
for (int i = 0; i < pairs.Length; i++) {
{ result.Add(pairs[i].Key, pairs[i].Value);
result.Add(pairs[i].Key, pairs[i].Value); }
} return result;
return result; }
}
static readonly string[] nix = new string[0];
static readonly string[] nix = new string[0]; /// <summary>
/// <summary> /// Create an array of strings from an array of values
/// Create an array of strings from an array of values /// </summary>
/// </summary> public static string[] ToStringArray(this RedisValue[] values)
public static string[] ToStringArray(this RedisValue[] values) {
{ if (values == null) return null;
if (values == null) return null; if (values.Length == 0) return nix;
if (values.Length == 0) return nix; return ConvertHelper.ConvertAll(values, x => (string)x);
return values.Select(x => (string)x).ToArray(); }
} }
} }
}
...@@ -133,7 +133,7 @@ internal static bool TryGetHostPort(EndPoint endpoint, out string host, out int ...@@ -133,7 +133,7 @@ internal static bool TryGetHostPort(EndPoint endpoint, out string host, out int
internal static bool TryParseDouble(string s, out double value) internal static bool TryParseDouble(string s, out double value)
{ {
if(s == null || s.Length == 0) if(string.IsNullOrEmpty(s))
{ {
value = 0; value = 0;
return false; return false;
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
/// <summary> /// <summary>
/// Describes a hash-field (a name/value pair) /// Describes a hash-field (a name/value pair)
/// </summary> /// </summary>
public struct HashEntry : IEquatable<HashEntry> public struct HashEntry : IEquatable<HashEntry>
{ {
internal readonly RedisValue name, value; internal readonly RedisValue name, value;
/// <summary> /// <summary>
/// Initializes a HashEntry value /// Initializes a HashEntry value
/// </summary> /// </summary>
public HashEntry(RedisValue name, RedisValue value) public HashEntry(RedisValue name, RedisValue value)
{ {
this.name = name; this.name = name;
this.value = value; this.value = value;
} }
/// <summary> /// <summary>
/// The name of the hash field /// The name of the hash field
/// </summary> /// </summary>
public RedisValue Name { get { return name; } } public RedisValue Name { get { return name; } }
/// <summary> /// <summary>
/// The value of the hash field /// The value of the hash field
/// </summary> /// </summary>
public RedisValue Value{ get { return value; } } public RedisValue Value{ get { return value; } }
/// <summary> /// <summary>
/// The name of the hash field /// The name of the hash field
/// </summary> /// </summary>
#if !DNXCORE50 #if !CORE_CLR
[Browsable(false)] [Browsable(false)]
#endif #endif
[EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)]
public RedisValue Key { get { return name; } } public RedisValue Key { get { return name; } }
/// <summary> /// <summary>
/// Converts to a key/value pair /// Converts to a key/value pair
/// </summary> /// </summary>
public static implicit operator KeyValuePair<RedisValue, RedisValue>(HashEntry value) public static implicit operator KeyValuePair<RedisValue, RedisValue>(HashEntry value)
{ {
return new KeyValuePair<RedisValue, RedisValue>(value.name, value.value); return new KeyValuePair<RedisValue, RedisValue>(value.name, value.value);
} }
/// <summary> /// <summary>
/// Converts from a key/value pair /// Converts from a key/value pair
/// </summary> /// </summary>
public static implicit operator HashEntry(KeyValuePair<RedisValue, RedisValue> value) public static implicit operator HashEntry(KeyValuePair<RedisValue, RedisValue> value)
{ {
return new HashEntry(value.Key, value.Value); return new HashEntry(value.Key, value.Value);
} }
/// <summary> /// <summary>
/// See Object.ToString() /// See Object.ToString()
/// </summary> /// </summary>
public override string ToString() public override string ToString()
{ {
return name + ": " + value; return name + ": " + value;
} }
/// <summary> /// <summary>
/// See Object.GetHashCode() /// See Object.GetHashCode()
/// </summary> /// </summary>
public override int GetHashCode() public override int GetHashCode()
{ {
return name.GetHashCode() ^ value.GetHashCode(); return name.GetHashCode() ^ value.GetHashCode();
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return obj is HashEntry && Equals((HashEntry)obj); return obj is HashEntry && Equals((HashEntry)obj);
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public bool Equals(HashEntry value) public bool Equals(HashEntry value)
{ {
return this.name == value.name && this.value == value.value; return this.name == value.name && this.value == value.value;
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public static bool operator ==(HashEntry x, HashEntry y) public static bool operator ==(HashEntry x, HashEntry y)
{ {
return x.name == y.name && x.value == y.value; return x.name == y.name && x.value == y.value;
} }
/// <summary> /// <summary>
/// Compares two values for non-equality /// Compares two values for non-equality
/// </summary> /// </summary>
public static bool operator !=(HashEntry x, HashEntry y) public static bool operator !=(HashEntry x, HashEntry y)
{ {
return x.name != y.name || x.value != y.value; return x.name != y.name || x.value != y.value;
} }
} }
} }
#if DNXCORE50 using System;
using System;
#endif
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
/// <summary>
/// Credits to Sam Harwell https://github.com/dotnet/corefx/issues/340#issuecomment-120749951
/// </summary>
internal static class InternalRegexCompiledOption internal static class InternalRegexCompiledOption
{ {
private static readonly RegexOptions RegexCompiledOption; private static readonly RegexOptions RegexCompiledOption;
static InternalRegexCompiledOption() static InternalRegexCompiledOption()
{ {
#if DNXCORE50 #if CORE_CLR
if (!Enum.TryParse("Compiled", out RegexCompiledOption)) if (!Enum.TryParse("Compiled", out RegexCompiledOption))
RegexCompiledOption = RegexOptions.None; RegexCompiledOption = RegexOptions.None;
#else #else
......
...@@ -335,12 +335,12 @@ public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = nu ...@@ -335,12 +335,12 @@ public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = nu
public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{ {
throw new NotImplementedException(); return this.Inner.ScriptEvaluateAsync(script, parameters, flags);
} }
public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{ {
throw new NotImplementedException(); return this.Inner.ScriptEvaluateAsync(script, parameters, flags);
} }
public Task<long> SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) public Task<long> SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
#if DNXCORE50 #if CORE_CLR
using System.Threading.Tasks; using System.Threading.Tasks;
#endif #endif
...@@ -131,7 +131,7 @@ public void Dispose() ...@@ -131,7 +131,7 @@ public void Dispose()
if (outStream != null) if (outStream != null)
{ {
multiplexer.Trace("Disconnecting...", physicalName); multiplexer.Trace("Disconnecting...", physicalName);
#if !DNXCORE50 #if !CORE_CLR
try { outStream.Close(); } catch { } try { outStream.Close(); } catch { }
#endif #endif
try { outStream.Dispose(); } catch { } try { outStream.Dispose(); } catch { }
...@@ -139,7 +139,7 @@ public void Dispose() ...@@ -139,7 +139,7 @@ public void Dispose()
} }
if (netStream != null) if (netStream != null)
{ {
#if !DNXCORE50 #if !CORE_CLR
try { netStream.Close(); } catch { } try { netStream.Close(); } catch { }
#endif #endif
try { netStream.Dispose(); } catch { } try { netStream.Dispose(); } catch { }
...@@ -603,6 +603,22 @@ unsafe void WriteRaw(Stream stream, string value, int encodedLength) ...@@ -603,6 +603,22 @@ unsafe void WriteRaw(Stream stream, string value, int encodedLength)
} }
else else
{ {
#if !CORE_CLR
fixed (char* c = value)
fixed (byte* b = outScratch)
{
int charsRemaining = value.Length, charOffset = 0, bytesWritten;
while (charsRemaining > Scratch_CharsPerBlock)
{
bytesWritten = outEncoder.GetBytes(c + charOffset, Scratch_CharsPerBlock, b, ScratchSize, false);
stream.Write(outScratch, 0, bytesWritten);
charOffset += Scratch_CharsPerBlock;
charsRemaining -= Scratch_CharsPerBlock;
}
bytesWritten = outEncoder.GetBytes(c + charOffset, charsRemaining, b, ScratchSize, true);
if (bytesWritten != 0) stream.Write(outScratch, 0, bytesWritten);
}
#else
int charsRemaining = value.Length, charOffset = 0, bytesWritten; int charsRemaining = value.Length, charOffset = 0, bytesWritten;
var valueCharArray = value.ToCharArray(); var valueCharArray = value.ToCharArray();
while (charsRemaining > Scratch_CharsPerBlock) while (charsRemaining > Scratch_CharsPerBlock)
...@@ -614,6 +630,7 @@ unsafe void WriteRaw(Stream stream, string value, int encodedLength) ...@@ -614,6 +630,7 @@ unsafe void WriteRaw(Stream stream, string value, int encodedLength)
} }
bytesWritten = outEncoder.GetBytes(valueCharArray, charOffset, charsRemaining, outScratch, 0, true); bytesWritten = outEncoder.GetBytes(valueCharArray, charOffset, charsRemaining, outScratch, 0, true);
if (bytesWritten != 0) stream.Write(outScratch, 0, bytesWritten); if (bytesWritten != 0) stream.Write(outScratch, 0, bytesWritten);
#endif
} }
} }
const int ScratchSize = 512; const int ScratchSize = 512;
...@@ -661,7 +678,7 @@ void BeginReading() ...@@ -661,7 +678,7 @@ void BeginReading()
int space = EnsureSpaceAndComputeBytesToRead(); int space = EnsureSpaceAndComputeBytesToRead();
multiplexer.Trace("Beginning async read...", physicalName); multiplexer.Trace("Beginning async read...", physicalName);
var result = netStream.BeginRead(ioBuffer, ioBufferBytes, space, endRead, this); var result = netStream.BeginRead(ioBuffer, ioBufferBytes, space, endRead, this);
#if DNXCORE50 #if CORE_CLR
Task<int> t = (Task<int>)result; Task<int> t = (Task<int>)result;
if (t.Status == TaskStatus.RanToCompletion && t.Result == -1) if (t.Status == TaskStatus.RanToCompletion && t.Result == -1)
{ {
...@@ -676,7 +693,7 @@ void BeginReading() ...@@ -676,7 +693,7 @@ void BeginReading()
} }
} while (keepReading); } while (keepReading);
} }
#if DNXCORE50 #if CORE_CLR
catch (AggregateException ex) catch (AggregateException ex)
{ {
throw ex.InnerException; throw ex.InnerException;
...@@ -759,7 +776,7 @@ SocketMode ISocketCallback.Connected(Stream stream, TextWriter log) ...@@ -759,7 +776,7 @@ SocketMode ISocketCallback.Connected(Stream stream, TextWriter log)
int bufferSize = config.WriteBuffer; int bufferSize = config.WriteBuffer;
this.netStream = stream; this.netStream = stream;
#if !DNXCORE50 #if !CORE_CLR
this.outStream = bufferSize <= 0 ? stream : new BufferedStream(stream, bufferSize); this.outStream = bufferSize <= 0 ? stream : new BufferedStream(stream, bufferSize);
#else #else
this.outStream = stream; this.outStream = stream;
...@@ -1096,7 +1113,7 @@ public void CheckForStaleConnection(ref SocketManager.ManagerState managerState) ...@@ -1096,7 +1113,7 @@ public void CheckForStaleConnection(ref SocketManager.ManagerState managerState)
} }
} }
#if DNXCORE50 #if CORE_CLR
internal static class StreamExtensions internal static class StreamExtensions
{ {
internal static IAsyncResult BeginRead(this Stream stream, byte[] buffer, int offset, int count, AsyncCallback ac, object state) internal static IAsyncResult BeginRead(this Stream stream, byte[] buffer, int offset, int count, AsyncCallback ac, object state)
......
...@@ -484,7 +484,7 @@ sealed class KeyMigrateCommandMessage : Message.CommandKeyBase // MIGRATE is aty ...@@ -484,7 +484,7 @@ sealed class KeyMigrateCommandMessage : Message.CommandKeyBase // MIGRATE is aty
public KeyMigrateCommandMessage(int db, RedisKey key, EndPoint toServer, int toDatabase, int timeoutMilliseconds, MigrateOptions migrateOptions, CommandFlags flags) public KeyMigrateCommandMessage(int db, RedisKey key, EndPoint toServer, int toDatabase, int timeoutMilliseconds, MigrateOptions migrateOptions, CommandFlags flags)
: base(db, flags, RedisCommand.MIGRATE, key) : base(db, flags, RedisCommand.MIGRATE, key)
{ {
if (toServer == null) throw new ArgumentNullException("server"); if (toServer == null) throw new ArgumentNullException("toServer");
string toHost; string toHost;
int toPort; int toPort;
if (!Format.TryGetHostPort(toServer, out toHost, out toPort)) throw new ArgumentException("toServer"); if (!Format.TryGetHostPort(toServer, out toHost, out toPort)) throw new ArgumentException("toServer");
......
using System; using System;
using System.Linq;
namespace StackExchange.Redis
namespace StackExchange.Redis {
{ /// <summary>
/// <summary> /// Represents a general-purpose result from redis, that may be cast into various anticipated types
/// Represents a general-purpose result from redis, that may be cast into various anticipated types /// </summary>
/// </summary> public abstract class RedisResult
public abstract class RedisResult {
{
// internally, this is very similar to RawResult, except it is designed to be usable
// internally, this is very similar to RawResult, except it is designed to be usable // outside of the IO-processing pipeline: the buffers are standalone, etc
// outside of the IO-processing pipeline: the buffers are standalone, etc
internal static RedisResult TryCreate(PhysicalConnection connection, RawResult result)
internal static RedisResult TryCreate(PhysicalConnection connection, RawResult result) {
{ try
try {
{ switch (result.Type)
switch (result.Type) {
{ case ResultType.Integer:
case ResultType.Integer: case ResultType.SimpleString:
case ResultType.SimpleString: case ResultType.BulkString:
case ResultType.BulkString: return new SingleRedisResult(result.AsRedisValue());
return new SingleRedisResult(result.AsRedisValue()); case ResultType.MultiBulk:
case ResultType.MultiBulk: var items = result.GetItems();
var items = result.GetItems(); var arr = new RedisResult[items.Length];
var arr = new RedisResult[items.Length]; for (int i = 0; i < arr.Length; i++)
for (int i = 0; i < arr.Length; i++) {
{ var next = TryCreate(connection, items[i]);
var next = TryCreate(connection, items[i]); if (next == null) return null; // means we didn't understand
if (next == null) return null; // means we didn't understand arr[i] = next;
arr[i] = next; }
} return new ArrayRedisResult(arr);
return new ArrayRedisResult(arr); case ResultType.Error:
case ResultType.Error: return new ErrorRedisResult(result.GetString());
return new ErrorRedisResult(result.GetString()); default:
default: return null;
return null; }
} } catch(Exception ex)
} catch(Exception ex) {
{ if(connection != null) connection.OnInternalError(ex);
if(connection != null) connection.OnInternalError(ex); return null; // will be logged as a protocol fail by the processor
return null; // will be logged as a protocol fail by the processor }
} }
}
/// <summary>
/// <summary> /// Indicates whether this result was a null result
/// Indicates whether this result was a null result /// </summary>
/// </summary> public abstract bool IsNull { get; }
public abstract bool IsNull { get; }
/// <summary>
/// <summary> /// Interprets the result as a String
/// Interprets the result as a String /// </summary>
/// </summary> public static explicit operator string (RedisResult result) { return result.AsString(); }
public static explicit operator string (RedisResult result) { return result.AsString(); } /// <summary>
/// <summary> /// Interprets the result as a Byte[]
/// Interprets the result as a Byte[] /// </summary>
/// </summary> public static explicit operator byte[] (RedisResult result) { return result.AsByteArray(); }
public static explicit operator byte[] (RedisResult result) { return result.AsByteArray(); } /// <summary>
/// <summary> /// Interprets the result as a Double
/// Interprets the result as a Double /// </summary>
/// </summary> public static explicit operator double (RedisResult result) { return result.AsDouble(); }
public static explicit operator double (RedisResult result) { return result.AsDouble(); } /// <summary>
/// <summary> /// Interprets the result as an Int64
/// Interprets the result as an Int64 /// </summary>
/// </summary> public static explicit operator long (RedisResult result) { return result.AsInt64(); }
public static explicit operator long (RedisResult result) { return result.AsInt64(); } /// <summary>
/// <summary> /// Interprets the result as an Int32
/// Interprets the result as an Int32 /// </summary>
/// </summary> public static explicit operator int (RedisResult result) { return result.AsInt32(); }
public static explicit operator int (RedisResult result) { return result.AsInt32(); } /// <summary>
/// <summary> /// Interprets the result as a Boolean
/// Interprets the result as a Boolean /// </summary>
/// </summary> public static explicit operator bool (RedisResult result) { return result.AsBoolean(); }
public static explicit operator bool (RedisResult result) { return result.AsBoolean(); } /// <summary>
/// <summary> /// Interprets the result as a RedisValue
/// Interprets the result as a RedisValue /// </summary>
/// </summary> public static explicit operator RedisValue (RedisResult result) { return result.AsRedisValue(); }
public static explicit operator RedisValue (RedisResult result) { return result.AsRedisValue(); } /// <summary>
/// <summary> /// Interprets the result as a RedisKey
/// Interprets the result as a RedisKey /// </summary>
/// </summary> public static explicit operator RedisKey (RedisResult result) { return result.AsRedisKey(); }
public static explicit operator RedisKey (RedisResult result) { return result.AsRedisKey(); } /// <summary>
/// <summary> /// Interprets the result as a Nullable Double
/// Interprets the result as a Nullable Double /// </summary>
/// </summary> public static explicit operator double? (RedisResult result) { return result.AsNullableDouble(); }
public static explicit operator double? (RedisResult result) { return result.AsNullableDouble(); } /// <summary>
/// <summary> /// Interprets the result as a Nullable Int64
/// Interprets the result as a Nullable Int64 /// </summary>
/// </summary> public static explicit operator long? (RedisResult result) { return result.AsNullableInt64(); }
public static explicit operator long? (RedisResult result) { return result.AsNullableInt64(); } /// <summary>
/// <summary> /// Interprets the result as a Nullable Int32
/// Interprets the result as a Nullable Int32 /// </summary>
/// </summary> public static explicit operator int? (RedisResult result) { return result.AsNullableInt32(); }
public static explicit operator int? (RedisResult result) { return result.AsNullableInt32(); } /// <summary>
/// <summary> /// Interprets the result as a Nullable Boolean
/// Interprets the result as a Nullable Boolean /// </summary>
/// </summary> public static explicit operator bool? (RedisResult result) { return result.AsNullableBoolean(); }
public static explicit operator bool? (RedisResult result) { return result.AsNullableBoolean(); } /// <summary>
/// <summary> /// Interprets the result as an array of String
/// Interprets the result as an array of String /// </summary>
/// </summary> public static explicit operator string[] (RedisResult result) { return result.AsStringArray(); }
public static explicit operator string[] (RedisResult result) { return result.AsStringArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of Byte[]
/// Interprets the result as an array of Byte[] /// </summary>
/// </summary> public static explicit operator byte[][] (RedisResult result) { return result.AsByteArrayArray(); }
public static explicit operator byte[][] (RedisResult result) { return result.AsByteArrayArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of Double
/// Interprets the result as an array of Double /// </summary>
/// </summary> public static explicit operator double[] (RedisResult result) { return result.AsDoubleArray(); }
public static explicit operator double[] (RedisResult result) { return result.AsDoubleArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of Int64
/// Interprets the result as an array of Int64 /// </summary>
/// </summary> public static explicit operator long[] (RedisResult result) { return result.AsInt64Array(); }
public static explicit operator long[] (RedisResult result) { return result.AsInt64Array(); } /// <summary>
/// <summary> /// Interprets the result as an array of Int32
/// Interprets the result as an array of Int32 /// </summary>
/// </summary> public static explicit operator int[] (RedisResult result) { return result.AsInt32Array(); }
public static explicit operator int[] (RedisResult result) { return result.AsInt32Array(); } /// <summary>
/// <summary> /// Interprets the result as an array of Boolean
/// Interprets the result as an array of Boolean /// </summary>
/// </summary> public static explicit operator bool[] (RedisResult result) { return result.AsBooleanArray(); }
public static explicit operator bool[] (RedisResult result) { return result.AsBooleanArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of RedisValue
/// Interprets the result as an array of RedisValue /// </summary>
/// </summary> public static explicit operator RedisValue[] (RedisResult result) { return result.AsRedisValueArray(); }
public static explicit operator RedisValue[] (RedisResult result) { return result.AsRedisValueArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of RedisKey
/// Interprets the result as an array of RedisKey /// </summary>
/// </summary> public static explicit operator RedisKey[] (RedisResult result) { return result.AsRedisKeyArray(); }
public static explicit operator RedisKey[] (RedisResult result) { return result.AsRedisKeyArray(); } /// <summary>
/// <summary> /// Interprets the result as an array of RedisResult
/// Interprets the result as an array of RedisResult /// </summary>
/// </summary> public static explicit operator RedisResult[] (RedisResult result) { return result.AsRedisResultArray(); }
public static explicit operator RedisResult[] (RedisResult result) { return result.AsRedisResultArray(); }
internal abstract bool AsBoolean();
internal abstract bool AsBoolean();
internal abstract bool[] AsBooleanArray();
internal abstract bool[] AsBooleanArray();
internal abstract byte[] AsByteArray();
internal abstract byte[] AsByteArray();
internal abstract byte[][] AsByteArrayArray();
internal abstract byte[][] AsByteArrayArray();
internal abstract double AsDouble();
internal abstract double AsDouble();
internal abstract double[] AsDoubleArray();
internal abstract double[] AsDoubleArray();
internal abstract int AsInt32();
internal abstract int AsInt32();
internal abstract int[] AsInt32Array();
internal abstract int[] AsInt32Array();
internal abstract long AsInt64();
internal abstract long AsInt64();
internal abstract long[] AsInt64Array();
internal abstract long[] AsInt64Array();
internal abstract bool? AsNullableBoolean();
internal abstract bool? AsNullableBoolean();
internal abstract double? AsNullableDouble();
internal abstract double? AsNullableDouble();
internal abstract int? AsNullableInt32();
internal abstract int? AsNullableInt32();
internal abstract long? AsNullableInt64();
internal abstract long? AsNullableInt64();
internal abstract RedisKey AsRedisKey();
internal abstract RedisKey AsRedisKey();
internal abstract RedisKey[] AsRedisKeyArray();
internal abstract RedisKey[] AsRedisKeyArray();
internal abstract RedisResult[] AsRedisResultArray();
internal abstract RedisResult[] AsRedisResultArray();
internal abstract RedisValue AsRedisValue();
internal abstract RedisValue AsRedisValue();
internal abstract RedisValue[] AsRedisValueArray();
internal abstract RedisValue[] AsRedisValueArray(); internal abstract string AsString();
internal abstract string AsString(); internal abstract string[] AsStringArray();
internal abstract string[] AsStringArray(); private sealed class ArrayRedisResult : RedisResult
private sealed class ArrayRedisResult : RedisResult {
{ public override bool IsNull
public override bool IsNull {
{ get { return value == null; }
get { return value == null; } }
} private readonly RedisResult[] value;
private readonly RedisResult[] value; public ArrayRedisResult(RedisResult[] value)
public ArrayRedisResult(RedisResult[] value) {
{ if (value == null) throw new ArgumentNullException("value");
if (value == null) throw new ArgumentNullException("value"); this.value = value;
this.value = value; }
} public override string ToString()
public override string ToString() {
{ return value.Length + " element(s)";
return value.Length + " element(s)"; }
} internal override bool AsBoolean()
internal override bool AsBoolean() {
{ if (value.Length == 1) return value[0].AsBoolean();
if (value.Length == 1) return value[0].AsBoolean(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override bool[] AsBooleanArray() { return ConvertHelper.ConvertAll(value, x => x.AsBoolean()); }
internal override bool[] AsBooleanArray() { return value.Select(x => x.AsBoolean()).ToArray(); }
internal override byte[] AsByteArray()
internal override byte[] AsByteArray() {
{ if (value.Length == 1) return value[0].AsByteArray();
if (value.Length == 1) return value[0].AsByteArray(); throw new InvalidCastException();
throw new InvalidCastException(); }
} internal override byte[][] AsByteArrayArray() { return ConvertHelper.ConvertAll(value, x => x.AsByteArray()); }
internal override byte[][] AsByteArrayArray() { return value.Select(x => x.AsByteArray()).ToArray(); }
internal override double AsDouble()
internal override double AsDouble() {
{ if (value.Length == 1) return value[0].AsDouble();
if (value.Length == 1) return value[0].AsDouble(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override double[] AsDoubleArray() { return ConvertHelper.ConvertAll(value, x => x.AsDouble()); }
internal override double[] AsDoubleArray() { return value.Select(x => x.AsDouble()).ToArray(); }
internal override int AsInt32()
internal override int AsInt32() {
{ if (value.Length == 1) return value[0].AsInt32();
if (value.Length == 1) return value[0].AsInt32(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override int[] AsInt32Array() { return ConvertHelper.ConvertAll(value, x => x.AsInt32()); }
internal override int[] AsInt32Array() { return value.Select(x => x.AsInt32()).ToArray(); }
internal override long AsInt64()
internal override long AsInt64() {
{ if (value.Length == 1) return value[0].AsInt64();
if (value.Length == 1) return value[0].AsInt64(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override long[] AsInt64Array() { return ConvertHelper.ConvertAll(value, x => x.AsInt64()); }
internal override long[] AsInt64Array() { return value.Select(x => x.AsInt64()).ToArray(); }
internal override bool? AsNullableBoolean()
internal override bool? AsNullableBoolean() {
{ if (value.Length == 1) return value[0].AsNullableBoolean();
if (value.Length == 1) return value[0].AsNullableBoolean(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override double? AsNullableDouble()
internal override double? AsNullableDouble() {
{ if (value.Length == 1) return value[0].AsNullableDouble();
if (value.Length == 1) return value[0].AsNullableDouble(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override int? AsNullableInt32()
internal override int? AsNullableInt32() {
{ if (value.Length == 1) return value[0].AsNullableInt32();
if (value.Length == 1) return value[0].AsNullableInt32(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override long? AsNullableInt64()
internal override long? AsNullableInt64() {
{ if (value.Length == 1) return value[0].AsNullableInt64();
if (value.Length == 1) return value[0].AsNullableInt64(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override RedisKey AsRedisKey()
internal override RedisKey AsRedisKey() {
{ if (value.Length == 1) return value[0].AsRedisKey();
if (value.Length == 1) return value[0].AsRedisKey(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override RedisKey[] AsRedisKeyArray() { return ConvertHelper.ConvertAll(value, x => x.AsRedisKey()); }
internal override RedisKey[] AsRedisKeyArray() { return value.Select(x => x.AsRedisKey()).ToArray(); }
internal override RedisResult[] AsRedisResultArray() { return value; }
internal override RedisResult[] AsRedisResultArray() { return value; }
internal override RedisValue AsRedisValue()
internal override RedisValue AsRedisValue() {
{ if (value.Length == 1) return value[0].AsRedisValue();
if (value.Length == 1) return value[0].AsRedisValue(); throw new InvalidCastException();
throw new InvalidCastException(); }
}
internal override RedisValue[] AsRedisValueArray() { return ConvertHelper.ConvertAll(value, x => x.AsRedisValue()); }
internal override RedisValue[] AsRedisValueArray() { return value.Select(x => x.AsRedisValue()).ToArray(); }
internal override string AsString()
internal override string AsString() {
{ if (value.Length == 1) return value[0].AsString();
if (value.Length == 1) return value[0].AsString(); throw new InvalidCastException();
throw new InvalidCastException(); }
} internal override string[] AsStringArray() { return ConvertHelper.ConvertAll(value, x => x.AsString()); }
internal override string[] AsStringArray() { return value.Select(x => x.AsString()).ToArray(); } }
}
private sealed class ErrorRedisResult : RedisResult
private sealed class ErrorRedisResult : RedisResult {
{ private readonly string value;
private readonly string value; public ErrorRedisResult(string value)
public ErrorRedisResult(string value) {
{ if (value == null) throw new ArgumentNullException("value");
if (value == null) throw new ArgumentNullException("value"); this.value = value;
this.value = value; }
} public override bool IsNull
public override bool IsNull {
{ get { return value == null; }
get { return value == null; } }
} public override string ToString() { return value; }
public override string ToString() { return value; } internal override bool AsBoolean() { throw new RedisServerException(value); }
internal override bool AsBoolean() { throw new RedisServerException(value); }
internal override bool[] AsBooleanArray() { throw new RedisServerException(value); }
internal override bool[] AsBooleanArray() { throw new RedisServerException(value); }
internal override byte[] AsByteArray() { throw new RedisServerException(value); }
internal override byte[] AsByteArray() { throw new RedisServerException(value); }
internal override byte[][] AsByteArrayArray() { throw new RedisServerException(value); }
internal override byte[][] AsByteArrayArray() { throw new RedisServerException(value); }
internal override double AsDouble() { throw new RedisServerException(value); }
internal override double AsDouble() { throw new RedisServerException(value); }
internal override double[] AsDoubleArray() { throw new RedisServerException(value); }
internal override double[] AsDoubleArray() { throw new RedisServerException(value); }
internal override int AsInt32() { throw new RedisServerException(value); }
internal override int AsInt32() { throw new RedisServerException(value); }
internal override int[] AsInt32Array() { throw new RedisServerException(value); }
internal override int[] AsInt32Array() { throw new RedisServerException(value); }
internal override long AsInt64() { throw new RedisServerException(value); }
internal override long AsInt64() { throw new RedisServerException(value); }
internal override long[] AsInt64Array() { throw new RedisServerException(value); }
internal override long[] AsInt64Array() { throw new RedisServerException(value); }
internal override bool? AsNullableBoolean() { throw new RedisServerException(value); }
internal override bool? AsNullableBoolean() { throw new RedisServerException(value); }
internal override double? AsNullableDouble() { throw new RedisServerException(value); }
internal override double? AsNullableDouble() { throw new RedisServerException(value); }
internal override int? AsNullableInt32() { throw new RedisServerException(value); }
internal override int? AsNullableInt32() { throw new RedisServerException(value); }
internal override long? AsNullableInt64() { throw new RedisServerException(value); }
internal override long? AsNullableInt64() { throw new RedisServerException(value); }
internal override RedisKey AsRedisKey() { throw new RedisServerException(value); }
internal override RedisKey AsRedisKey() { throw new RedisServerException(value); }
internal override RedisKey[] AsRedisKeyArray() { throw new RedisServerException(value); }
internal override RedisKey[] AsRedisKeyArray() { throw new RedisServerException(value); }
internal override RedisResult[] AsRedisResultArray() { throw new RedisServerException(value); }
internal override RedisResult[] AsRedisResultArray() { throw new RedisServerException(value); }
internal override RedisValue AsRedisValue() { throw new RedisServerException(value); }
internal override RedisValue AsRedisValue() { throw new RedisServerException(value); }
internal override RedisValue[] AsRedisValueArray() { throw new RedisServerException(value); }
internal override RedisValue[] AsRedisValueArray() { throw new RedisServerException(value); }
internal override string AsString() { throw new RedisServerException(value); }
internal override string AsString() { throw new RedisServerException(value); } internal override string[] AsStringArray() { throw new RedisServerException(value); }
internal override string[] AsStringArray() { throw new RedisServerException(value); } }
}
private sealed class SingleRedisResult : RedisResult
private sealed class SingleRedisResult : RedisResult {
{ private readonly RedisValue value;
private readonly RedisValue value; public SingleRedisResult(RedisValue value)
public SingleRedisResult(RedisValue value) {
{ this.value = value;
this.value = value; }
}
public override bool IsNull
public override bool IsNull {
{ get { return value.IsNull; }
get { return value.IsNull; } }
}
public override string ToString() { return value.ToString(); }
public override string ToString() { return value.ToString(); } internal override bool AsBoolean() { return (bool)value; }
internal override bool AsBoolean() { return (bool)value; }
internal override bool[] AsBooleanArray() { return new[] { AsBoolean() }; }
internal override bool[] AsBooleanArray() { return new[] { AsBoolean() }; }
internal override byte[] AsByteArray() { return (byte[])value; }
internal override byte[] AsByteArray() { return (byte[])value; } internal override byte[][] AsByteArrayArray() { return new[] { AsByteArray() }; }
internal override byte[][] AsByteArrayArray() { return new[] { AsByteArray() }; }
internal override double AsDouble() { return (double)value; }
internal override double AsDouble() { return (double)value; }
internal override double[] AsDoubleArray() { return new[] { AsDouble() }; }
internal override double[] AsDoubleArray() { return new[] { AsDouble() }; }
internal override int AsInt32() { return (int)value; }
internal override int AsInt32() { return (int)value; }
internal override int[] AsInt32Array() { return new[] { AsInt32() }; }
internal override int[] AsInt32Array() { return new[] { AsInt32() }; }
internal override long AsInt64() { return (long)value; }
internal override long AsInt64() { return (long)value; }
internal override long[] AsInt64Array() { return new[] { AsInt64() }; }
internal override long[] AsInt64Array() { return new[] { AsInt64() }; }
internal override bool? AsNullableBoolean() { return (bool?)value; }
internal override bool? AsNullableBoolean() { return (bool?)value; }
internal override double? AsNullableDouble() { return (double?)value; }
internal override double? AsNullableDouble() { return (double?)value; }
internal override int? AsNullableInt32() { return (int?)value; }
internal override int? AsNullableInt32() { return (int?)value; }
internal override long? AsNullableInt64() { return (long?)value; }
internal override long? AsNullableInt64() { return (long?)value; }
internal override RedisKey AsRedisKey() { return (byte[])value; }
internal override RedisKey AsRedisKey() { return (byte[])value; }
internal override RedisKey[] AsRedisKeyArray() { return new[] { AsRedisKey() }; }
internal override RedisKey[] AsRedisKeyArray() { return new[] { AsRedisKey() }; }
internal override RedisResult[] AsRedisResultArray() { throw new InvalidCastException(); }
internal override RedisResult[] AsRedisResultArray() { throw new InvalidCastException(); }
internal override RedisValue AsRedisValue() { return value; }
internal override RedisValue AsRedisValue() { return value; }
internal override RedisValue[] AsRedisValueArray() { return new[] { AsRedisValue() }; }
internal override RedisValue[] AsRedisValueArray() { return new[] { AsRedisValue() }; }
internal override string AsString() { return (string)value; }
internal override string AsString() { return (string)value; } internal override string[] AsStringArray() { return new[] { AsString() }; }
internal override string[] AsStringArray() { return new[] { AsString() }; } }
} }
} }
}
using System; using System;
#if DNXCORE50 #if CORE_CLR
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
#endif #endif
...@@ -306,11 +306,11 @@ public int CompareTo(RedisValue other) ...@@ -306,11 +306,11 @@ public int CompareTo(RedisValue other)
if (otherType == CompareType.Double) return thisDouble.CompareTo(otherDouble); if (otherType == CompareType.Double) return thisDouble.CompareTo(otherDouble);
} }
// otherwise, compare as strings // otherwise, compare as strings
#if !DNXCORE50 #if !CORE_CLR
return StringComparer.InvariantCulture.Compare((string)this, (string)other); return StringComparer.InvariantCulture.Compare((string)this, (string)other);
#else #else
var compareInfo = System.Globalization.CultureInfo.InvariantCulture.CompareInfo; var compareInfo = System.Globalization.CultureInfo.InvariantCulture.CompareInfo;
return compareInfo.Compare((string)this, (string)other, System.Globalization.CompareOptions.IgnoreCase); return compareInfo.Compare((string)this, (string)other, System.Globalization.CompareOptions.Ordinal);
#endif #endif
} }
catch(Exception ex) catch(Exception ex)
...@@ -716,7 +716,7 @@ public bool TryParse(out double val) ...@@ -716,7 +716,7 @@ public bool TryParse(out double val)
internal static class ReflectionExtensions internal static class ReflectionExtensions
{ {
#if DNXCORE50 #if CORE_CLR
internal static TypeCode GetTypeCode(this Type type) internal static TypeCode GetTypeCode(this Type type)
{ {
if (type == null) return TypeCode.Empty; if (type == null) return TypeCode.Empty;
......
...@@ -313,7 +313,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc ...@@ -313,7 +313,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc
LocalBuilder redisKeyLoc = null; LocalBuilder redisKeyLoc = null;
var loc = il.DeclareLocal(t); var loc = il.DeclareLocal(t);
il.Emit(OpCodes.Ldarg_0); // object il.Emit(OpCodes.Ldarg_0); // object
#if !DNXCORE50 #if !CORE_CLR
if (t.IsValueType) if (t.IsValueType)
#else #else
if (t.GetTypeInfo().IsValueType) if (t.GetTypeInfo().IsValueType)
...@@ -348,7 +348,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc ...@@ -348,7 +348,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc
{ {
il.Emit(OpCodes.Dup); // RedisKey[] RedisKey[] il.Emit(OpCodes.Dup); // RedisKey[] RedisKey[]
il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisKey[] int il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisKey[] int
#if !DNXCORE50 #if !CORE_CLR
if (t.IsValueType) if (t.IsValueType)
#else #else
if (t.GetTypeInfo().IsValueType) if (t.GetTypeInfo().IsValueType)
...@@ -380,7 +380,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc ...@@ -380,7 +380,7 @@ static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref Loc
{ {
il.Emit(OpCodes.Dup); // RedisKey[] RedisValue[] RedisValue[] il.Emit(OpCodes.Dup); // RedisKey[] RedisValue[] RedisValue[]
il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisValue[] RedisValue[] int il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisValue[] RedisValue[] int
#if !DNXCORE50 #if !CORE_CLR
if (t.IsValueType) if (t.IsValueType)
#else #else
if (t.GetTypeInfo().IsValueType) if (t.GetTypeInfo().IsValueType)
......
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
[Flags] [Flags]
internal enum UnselectableFlags internal enum UnselectableFlags
{ {
None = 0, None = 0,
RedundantMaster = 1, RedundantMaster = 1,
DidNotRespond = 2, DidNotRespond = 2,
ServerType = 4 ServerType = 4
} }
internal sealed partial class ServerEndPoint : IDisposable internal sealed partial class ServerEndPoint : IDisposable
{ {
internal volatile ServerEndPoint Master; internal volatile ServerEndPoint Master;
internal volatile ServerEndPoint[] Slaves = NoSlaves; internal volatile ServerEndPoint[] Slaves = NoSlaves;
private static readonly Regex nameSanitizer = new Regex("[^!-~]", InternalRegexCompiledOption.Default); private static readonly Regex nameSanitizer = new Regex("[^!-~]", InternalRegexCompiledOption.Default);
private static readonly ServerEndPoint[] NoSlaves = new ServerEndPoint[0]; private static readonly ServerEndPoint[] NoSlaves = new ServerEndPoint[0];
private readonly EndPoint endpoint; private readonly EndPoint endpoint;
private readonly Hashtable knownScripts = new Hashtable(StringComparer.Ordinal); private readonly Hashtable knownScripts = new Hashtable(StringComparer.Ordinal);
private readonly ConnectionMultiplexer multiplexer; private readonly ConnectionMultiplexer multiplexer;
private int databases, writeEverySeconds; private int databases, writeEverySeconds;
private PhysicalBridge interactive, subscription; private PhysicalBridge interactive, subscription;
bool isDisposed; bool isDisposed;
ServerType serverType; ServerType serverType;
private bool slaveReadOnly, isSlave; private bool slaveReadOnly, isSlave;
private volatile UnselectableFlags unselectableReasons; private volatile UnselectableFlags unselectableReasons;
private Version version; private Version version;
internal void ResetNonConnected() internal void ResetNonConnected()
{ {
var tmp = interactive; var tmp = interactive;
if (tmp != null) tmp.ResetNonConnected(); if (tmp != null) tmp.ResetNonConnected();
tmp = subscription; tmp = subscription;
if (tmp != null) tmp.ResetNonConnected(); if (tmp != null) tmp.ResetNonConnected();
} }
public ServerEndPoint(ConnectionMultiplexer multiplexer, EndPoint endpoint, TextWriter log) public ServerEndPoint(ConnectionMultiplexer multiplexer, EndPoint endpoint, TextWriter log)
{ {
this.multiplexer = multiplexer; this.multiplexer = multiplexer;
this.endpoint = endpoint; this.endpoint = endpoint;
var config = multiplexer.RawConfig; var config = multiplexer.RawConfig;
version = config.DefaultVersion; version = config.DefaultVersion;
slaveReadOnly = true; slaveReadOnly = true;
isSlave = false; isSlave = false;
databases = 0; databases = 0;
writeEverySeconds = config.KeepAlive > 0 ? config.KeepAlive : 60; writeEverySeconds = config.KeepAlive > 0 ? config.KeepAlive : 60;
interactive = CreateBridge(ConnectionType.Interactive, log); interactive = CreateBridge(ConnectionType.Interactive, log);
serverType = ServerType.Standalone; serverType = ServerType.Standalone;
// overrides for twemproxy // overrides for twemproxy
if (multiplexer.RawConfig.Proxy == Proxy.Twemproxy) if (multiplexer.RawConfig.Proxy == Proxy.Twemproxy)
{ {
databases = 1; databases = 1;
serverType = ServerType.Twemproxy; serverType = ServerType.Twemproxy;
} }
} }
public ClusterConfiguration ClusterConfiguration { get; private set; } public ClusterConfiguration ClusterConfiguration { get; private set; }
public int Databases { get { return databases; } set { SetConfig(ref databases, value); } } public int Databases { get { return databases; } set { SetConfig(ref databases, value); } }
public EndPoint EndPoint { get { return endpoint; } } public EndPoint EndPoint { get { return endpoint; } }
public bool HasDatabases { get { return serverType == ServerType.Standalone; } } public bool HasDatabases { get { return serverType == ServerType.Standalone; } }
public bool IsConnected public bool IsConnected
{ {
get get
{ {
var tmp = interactive; var tmp = interactive;
return tmp != null && tmp.IsConnected; return tmp != null && tmp.IsConnected;
} }
} }
public bool IsSlave { get { return isSlave; } set { SetConfig(ref isSlave, value); } } public bool IsSlave { get { return isSlave; } set { SetConfig(ref isSlave, value); } }
public long OperationCount public long OperationCount
{ {
get get
{ {
long total = 0; long total = 0;
var tmp = interactive; var tmp = interactive;
if (tmp != null) total += tmp.OperationCount; if (tmp != null) total += tmp.OperationCount;
tmp = subscription; tmp = subscription;
if (tmp != null) total += tmp.OperationCount; if (tmp != null) total += tmp.OperationCount;
return total; return total;
} }
} }
public bool RequiresReadMode { get { return serverType == ServerType.Cluster && IsSlave; } } public bool RequiresReadMode { get { return serverType == ServerType.Cluster && IsSlave; } }
public ServerType ServerType { get { return serverType; } set { SetConfig(ref serverType, value); } } public ServerType ServerType { get { return serverType; } set { SetConfig(ref serverType, value); } }
public bool SlaveReadOnly { get { return slaveReadOnly; } set { SetConfig(ref slaveReadOnly, value); } } public bool SlaveReadOnly { get { return slaveReadOnly; } set { SetConfig(ref slaveReadOnly, value); } }
public bool AllowSlaveWrites { get; set; } public bool AllowSlaveWrites { get; set; }
public Version Version { get { return version; } set { SetConfig(ref version, value); } } public Version Version { get { return version; } set { SetConfig(ref version, value); } }
public int WriteEverySeconds { get { return writeEverySeconds; } set { SetConfig(ref writeEverySeconds, value); } } public int WriteEverySeconds { get { return writeEverySeconds; } set { SetConfig(ref writeEverySeconds, value); } }
internal ConnectionMultiplexer Multiplexer { get { return multiplexer; } } internal ConnectionMultiplexer Multiplexer { get { return multiplexer; } }
public void ClearUnselectable(UnselectableFlags flags) public void ClearUnselectable(UnselectableFlags flags)
{ {
var oldFlags = unselectableReasons; var oldFlags = unselectableReasons;
if (oldFlags != 0) if (oldFlags != 0)
{ {
unselectableReasons &= ~flags; unselectableReasons &= ~flags;
if (unselectableReasons != oldFlags) if (unselectableReasons != oldFlags)
{ {
multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString()); multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString());
} }
} }
} }
public void Dispose() public void Dispose()
{ {
isDisposed = true; isDisposed = true;
var tmp = interactive; var tmp = interactive;
interactive = null; interactive = null;
if (tmp != null) tmp.Dispose(); if (tmp != null) tmp.Dispose();
tmp = subscription; tmp = subscription;
subscription = null; subscription = null;
if (tmp != null) tmp.Dispose(); if (tmp != null) tmp.Dispose();
} }
public PhysicalBridge GetBridge(ConnectionType type, bool create = true, TextWriter log = null) public PhysicalBridge GetBridge(ConnectionType type, bool create = true, TextWriter log = null)
{ {
if (isDisposed) return null; if (isDisposed) return null;
switch (type) switch (type)
{ {
case ConnectionType.Interactive: case ConnectionType.Interactive:
return interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, log) : null); return interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, log) : null);
case ConnectionType.Subscription: case ConnectionType.Subscription:
return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, log) : null); return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, log) : null);
} }
return null; return null;
} }
public PhysicalBridge GetBridge(RedisCommand command, bool create = true) public PhysicalBridge GetBridge(RedisCommand command, bool create = true)
{ {
if (isDisposed) return null; if (isDisposed) return null;
switch (command) switch (command)
{ {
case RedisCommand.SUBSCRIBE: case RedisCommand.SUBSCRIBE:
case RedisCommand.UNSUBSCRIBE: case RedisCommand.UNSUBSCRIBE:
case RedisCommand.PSUBSCRIBE: case RedisCommand.PSUBSCRIBE:
case RedisCommand.PUNSUBSCRIBE: case RedisCommand.PUNSUBSCRIBE:
return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, null) : null); return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, null) : null);
default: default:
return interactive; return interactive;
} }
} }
public RedisFeatures GetFeatures() public RedisFeatures GetFeatures()
{ {
return new RedisFeatures(version); return new RedisFeatures(version);
} }
public void SetClusterConfiguration(ClusterConfiguration configuration) public void SetClusterConfiguration(ClusterConfiguration configuration)
{ {
ClusterConfiguration = configuration; ClusterConfiguration = configuration;
if (configuration != null) if (configuration != null)
{ {
multiplexer.Trace("Updating cluster ranges..."); multiplexer.Trace("Updating cluster ranges...");
multiplexer.UpdateClusterRange(configuration); multiplexer.UpdateClusterRange(configuration);
multiplexer.Trace("Resolving genealogy..."); multiplexer.Trace("Resolving genealogy...");
var thisNode = configuration.Nodes.FirstOrDefault(x => x.EndPoint == this.EndPoint); var thisNode = configuration.Nodes.FirstOrDefault(x => x.EndPoint == this.EndPoint);
if (thisNode != null) if (thisNode != null)
{ {
List<ServerEndPoint> slaves = null; List<ServerEndPoint> slaves = null;
ServerEndPoint master = null; ServerEndPoint master = null;
foreach (var node in configuration.Nodes) foreach (var node in configuration.Nodes)
{ {
if (node.NodeId == thisNode.ParentNodeId) if (node.NodeId == thisNode.ParentNodeId)
{ {
master = multiplexer.GetServerEndPoint(node.EndPoint); master = multiplexer.GetServerEndPoint(node.EndPoint);
} }
else if (node.ParentNodeId == thisNode.NodeId) else if (node.ParentNodeId == thisNode.NodeId)
{ {
if (slaves == null) slaves = new List<ServerEndPoint>(); if (slaves == null) slaves = new List<ServerEndPoint>();
slaves.Add(multiplexer.GetServerEndPoint(node.EndPoint)); slaves.Add(multiplexer.GetServerEndPoint(node.EndPoint));
} }
} }
Master = master; Master = master;
Slaves = slaves == null ? NoSlaves : slaves.ToArray(); Slaves = slaves == null ? NoSlaves : slaves.ToArray();
} }
multiplexer.Trace("Cluster configured"); multiplexer.Trace("Cluster configured");
} }
} }
public void SetUnselectable(UnselectableFlags flags) public void SetUnselectable(UnselectableFlags flags)
{ {
if (flags != 0) if (flags != 0)
{ {
var oldFlags = unselectableReasons; var oldFlags = unselectableReasons;
unselectableReasons |= flags; unselectableReasons |= flags;
if (unselectableReasons != oldFlags) if (unselectableReasons != oldFlags)
{ {
multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString()); multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString());
} }
} }
} }
public override string ToString() public override string ToString()
{ {
return Format.ToString(EndPoint); return Format.ToString(EndPoint);
} }
public bool TryEnqueue(Message message) public bool TryEnqueue(Message message)
{ {
var bridge = GetBridge(message.Command); var bridge = GetBridge(message.Command);
return bridge != null && bridge.TryEnqueue(message, isSlave); return bridge != null && bridge.TryEnqueue(message, isSlave);
} }
internal void Activate(ConnectionType type, TextWriter log) internal void Activate(ConnectionType type, TextWriter log)
{ {
GetBridge(type, true, log); GetBridge(type, true, log);
} }
internal void AddScript(string script, byte[] hash) internal void AddScript(string script, byte[] hash)
{ {
lock (knownScripts) lock (knownScripts)
{ {
knownScripts[script] = hash; knownScripts[script] = hash;
} }
} }
internal void AutoConfigure(PhysicalConnection connection) internal void AutoConfigure(PhysicalConnection connection)
{ {
if (serverType == ServerType.Twemproxy) if (serverType == ServerType.Twemproxy)
{ {
// don't try to detect configuration; all the config commands are disabled, and // don't try to detect configuration; all the config commands are disabled, and
// the fallback master/slave detection won't help // the fallback master/slave detection won't help
return; return;
} }
var commandMap = multiplexer.CommandMap; var commandMap = multiplexer.CommandMap;
const CommandFlags flags = CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect; const CommandFlags flags = CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect;
var features = GetFeatures(); var features = GetFeatures();
Message msg; Message msg;
if (commandMap.IsAvailable(RedisCommand.CONFIG)) if (commandMap.IsAvailable(RedisCommand.CONFIG))
{ {
if (multiplexer.RawConfig.KeepAlive <= 0) if (multiplexer.RawConfig.KeepAlive <= 0)
{ {
msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.timeout); msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.timeout);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
} }
msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.slave_read_only); msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.slave_read_only);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.databases); msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.databases);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
} }
if (commandMap.IsAvailable(RedisCommand.INFO)) if (commandMap.IsAvailable(RedisCommand.INFO))
{ {
lastInfoReplicationCheckTicks = Environment.TickCount; lastInfoReplicationCheckTicks = Environment.TickCount;
if (features.InfoSections) if (features.InfoSections)
{ {
msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.replication); msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.replication);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.server); msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.server);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
} }
else else
{ {
msg = Message.Create(-1, flags, RedisCommand.INFO); msg = Message.Create(-1, flags, RedisCommand.INFO);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
} }
} }
else if (commandMap.IsAvailable(RedisCommand.SET)) else if (commandMap.IsAvailable(RedisCommand.SET))
{ {
// this is a nasty way to find if we are a slave, and it will only work on up-level servers, but... // this is a nasty way to find if we are a slave, and it will only work on up-level servers, but...
RedisKey key = Guid.NewGuid().ToByteArray(); RedisKey key = Guid.NewGuid().ToByteArray();
msg = Message.Create(0, flags, RedisCommand.SET, key, RedisLiterals.slave_read_only, RedisLiterals.PX, 1, RedisLiterals.NX); msg = Message.Create(0, flags, RedisCommand.SET, key, RedisLiterals.slave_read_only, RedisLiterals.PX, 1, RedisLiterals.NX);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure);
} }
if (commandMap.IsAvailable(RedisCommand.CLUSTER)) if (commandMap.IsAvailable(RedisCommand.CLUSTER))
{ {
msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.ClusterNodes); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.ClusterNodes);
} }
} }
internal Task Close() internal Task Close()
{ {
var tmp = interactive; var tmp = interactive;
Task result; Task result;
if (tmp == null || !tmp.IsConnected || !multiplexer.CommandMap.IsAvailable(RedisCommand.QUIT)) if (tmp == null || !tmp.IsConnected || !multiplexer.CommandMap.IsAvailable(RedisCommand.QUIT))
{ {
result = CompletedTask<bool>.Default(null); result = CompletedTask<bool>.Default(null);
} }
else else
{ {
result = QueueDirectAsync(Message.Create(-1, CommandFlags.None, RedisCommand.QUIT), ResultProcessor.DemandOK, bridge: interactive); result = QueueDirectAsync(Message.Create(-1, CommandFlags.None, RedisCommand.QUIT), ResultProcessor.DemandOK, bridge: interactive);
} }
return result; return result;
} }
internal void FlushScriptCache() internal void FlushScriptCache()
{ {
lock (knownScripts) lock (knownScripts)
{ {
knownScripts.Clear(); knownScripts.Clear();
} }
} }
private string runId; private string runId;
internal string RunId internal string RunId
{ {
get { return runId; } get { return runId; }
set set
{ {
if (value != runId) // we only care about changes if (value != runId) // we only care about changes
{ {
// if we had an old run-id, and it has changed, then the // if we had an old run-id, and it has changed, then the
// server has been restarted; which means the script cache // server has been restarted; which means the script cache
// is toast // is toast
if (runId != null) FlushScriptCache(); if (runId != null) FlushScriptCache();
runId = value; runId = value;
} }
} }
} }
internal ServerCounters GetCounters() internal ServerCounters GetCounters()
{ {
var counters = new ServerCounters(endpoint); var counters = new ServerCounters(endpoint);
var tmp = interactive; var tmp = interactive;
if (tmp != null) tmp.GetCounters(counters.Interactive); if (tmp != null) tmp.GetCounters(counters.Interactive);
tmp = subscription; tmp = subscription;
if (tmp != null) tmp.GetCounters(counters.Subscription); if (tmp != null) tmp.GetCounters(counters.Subscription);
return counters; return counters;
} }
internal int GetOutstandingCount(RedisCommand command, out int inst, out int qu, out int qs, out int qc, out int wr, out int wq, out int @in, out int ar) internal int GetOutstandingCount(RedisCommand command, out int inst, out int qu, out int qs, out int qc, out int wr, out int wq, out int @in, out int ar)
{ {
var bridge = GetBridge(command, false); var bridge = GetBridge(command, false);
if (bridge == null) if (bridge == null)
{ {
return inst = qu = qs = qc = wr = wq = @in = ar = 0; return inst = qu = qs = qc = wr = wq = @in = ar = 0;
} }
return bridge.GetOutstandingCount(out inst, out qu, out qs, out qc, out wr, out wq, out @in, out ar); return bridge.GetOutstandingCount(out inst, out qu, out qs, out qc, out wr, out wq, out @in, out ar);
} }
internal string GetProfile() internal string GetProfile()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append("Circular op-count snapshot; int:"); sb.Append("Circular op-count snapshot; int:");
var tmp = interactive; var tmp = interactive;
if (tmp != null) tmp.AppendProfile(sb); if (tmp != null) tmp.AppendProfile(sb);
sb.Append("; sub:"); sb.Append("; sub:");
tmp = subscription; tmp = subscription;
if (tmp != null) tmp.AppendProfile(sb); if (tmp != null) tmp.AppendProfile(sb);
return sb.ToString(); return sb.ToString();
} }
internal byte[] GetScriptHash(string script, RedisCommand command) internal byte[] GetScriptHash(string script, RedisCommand command)
{ {
var found = (byte[])knownScripts[script]; var found = (byte[])knownScripts[script];
if(found == null && command == RedisCommand.EVALSHA) if(found == null && command == RedisCommand.EVALSHA)
{ {
// the script provided is a hex sha; store and re-use the ascii for that // the script provided is a hex sha; store and re-use the ascii for that
found = Encoding.ASCII.GetBytes(script); found = Encoding.ASCII.GetBytes(script);
lock(knownScripts) lock(knownScripts)
{ {
knownScripts[script] = found; knownScripts[script] = found;
} }
} }
return found; return found;
} }
internal string GetStormLog(RedisCommand command) internal string GetStormLog(RedisCommand command)
{ {
var bridge = GetBridge(command); var bridge = GetBridge(command);
return bridge == null ? null : bridge.GetStormLog(); return bridge == null ? null : bridge.GetStormLog();
} }
internal Message GetTracerMessage(bool assertIdentity) internal Message GetTracerMessage(bool assertIdentity)
{ {
// different configurations block certain commands, as can ad-hoc local configurations, so // different configurations block certain commands, as can ad-hoc local configurations, so
// we'll do the best with what we have available. // we'll do the best with what we have available.
// note that the muxer-ctor asserts that one of ECHO, PING, TIME of GET is available // note that the muxer-ctor asserts that one of ECHO, PING, TIME of GET is available
// see also: TracerProcessor // see also: TracerProcessor
var map = multiplexer.CommandMap; var map = multiplexer.CommandMap;
Message msg; Message msg;
const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.FireAndForget; const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.FireAndForget;
if (assertIdentity && map.IsAvailable(RedisCommand.ECHO)) if (assertIdentity && map.IsAvailable(RedisCommand.ECHO))
{ {
msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId); msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId);
} }
else if (map.IsAvailable(RedisCommand.PING)) else if (map.IsAvailable(RedisCommand.PING))
{ {
msg = Message.Create(-1, flags, RedisCommand.PING); msg = Message.Create(-1, flags, RedisCommand.PING);
} }
else if (map.IsAvailable(RedisCommand.TIME)) else if (map.IsAvailable(RedisCommand.TIME))
{ {
msg = Message.Create(-1, flags, RedisCommand.TIME); msg = Message.Create(-1, flags, RedisCommand.TIME);
} }
else if (!assertIdentity && map.IsAvailable(RedisCommand.ECHO)) else if (!assertIdentity && map.IsAvailable(RedisCommand.ECHO))
{ {
// we'll use echo as a PING substitute if it is all we have (in preference to EXISTS) // we'll use echo as a PING substitute if it is all we have (in preference to EXISTS)
msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId); msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId);
} }
else else
{ {
map.AssertAvailable(RedisCommand.EXISTS); map.AssertAvailable(RedisCommand.EXISTS);
msg = Message.Create(0, flags, RedisCommand.EXISTS, (RedisValue)multiplexer.UniqueId); msg = Message.Create(0, flags, RedisCommand.EXISTS, (RedisValue)multiplexer.UniqueId);
} }
msg.SetInternalCall(); msg.SetInternalCall();
return msg; return msg;
} }
internal bool IsSelectable(RedisCommand command) internal bool IsSelectable(RedisCommand command)
{ {
var bridge = unselectableReasons == 0 ? GetBridge(command, false) : null; var bridge = unselectableReasons == 0 ? GetBridge(command, false) : null;
return bridge != null && bridge.IsConnected; return bridge != null && bridge.IsConnected;
} }
internal void OnEstablishing(PhysicalConnection connection, TextWriter log) internal void OnEstablishing(PhysicalConnection connection, TextWriter log)
{ {
try try
{ {
if (connection == null) return; if (connection == null) return;
Handshake(connection, log); Handshake(connection, log);
} }
catch (Exception ex) catch (Exception ex)
{ {
connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex);
} }
} }
internal void OnFullyEstablished(PhysicalConnection connection) internal void OnFullyEstablished(PhysicalConnection connection)
{ {
try try
{ {
if (connection == null) return; if (connection == null) return;
var bridge = connection.Bridge; var bridge = connection.Bridge;
if (bridge == subscription) if (bridge == subscription)
{ {
multiplexer.ResendSubscriptions(this); multiplexer.ResendSubscriptions(this);
} }
multiplexer.OnConnectionRestored(endpoint, bridge.ConnectionType); multiplexer.OnConnectionRestored(endpoint, bridge.ConnectionType);
} }
catch (Exception ex) catch (Exception ex)
{ {
connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex);
} }
} }
internal int LastInfoReplicationCheckSecondsAgo internal int LastInfoReplicationCheckSecondsAgo
{ {
get { return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastInfoReplicationCheckTicks)) / 1000; } get { return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastInfoReplicationCheckTicks)) / 1000; }
} }
private EndPoint masterEndPoint; private EndPoint masterEndPoint;
public EndPoint MasterEndPoint public EndPoint MasterEndPoint
{ {
get { return masterEndPoint; } get { return masterEndPoint; }
set { SetConfig(ref masterEndPoint, value); } set { SetConfig(ref masterEndPoint, value); }
} }
internal bool CheckInfoReplication() internal bool CheckInfoReplication()
{ {
lastInfoReplicationCheckTicks = Environment.TickCount; lastInfoReplicationCheckTicks = Environment.TickCount;
PhysicalBridge bridge; PhysicalBridge bridge;
if (version >= RedisFeatures.v2_8_0 && multiplexer.CommandMap.IsAvailable(RedisCommand.INFO) if (version >= RedisFeatures.v2_8_0 && multiplexer.CommandMap.IsAvailable(RedisCommand.INFO)
&& (bridge = GetBridge(ConnectionType.Interactive, false)) != null) && (bridge = GetBridge(ConnectionType.Interactive, false)) != null)
{ {
var msg = Message.Create(-1, CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect, RedisCommand.INFO, RedisLiterals.replication); var msg = Message.Create(-1, CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect, RedisCommand.INFO, RedisLiterals.replication);
msg.SetInternalCall(); msg.SetInternalCall();
QueueDirectFireAndForget(msg, ResultProcessor.AutoConfigure, bridge); QueueDirectFireAndForget(msg, ResultProcessor.AutoConfigure, bridge);
return true; return true;
} }
return false; return false;
} }
private int lastInfoReplicationCheckTicks; private int lastInfoReplicationCheckTicks;
internal void OnHeartbeat() internal void OnHeartbeat()
{ {
try try
{ {
var tmp = interactive; var tmp = interactive;
if (tmp != null) tmp.OnHeartbeat(false); if (tmp != null) tmp.OnHeartbeat(false);
tmp = subscription; tmp = subscription;
if (tmp != null) tmp.OnHeartbeat(false); if (tmp != null) tmp.OnHeartbeat(false);
} catch(Exception ex) } catch(Exception ex)
{ {
multiplexer.OnInternalError(ex, EndPoint); multiplexer.OnInternalError(ex, EndPoint);
} }
} }
internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> processor, object asyncState = null, PhysicalBridge bridge = null) internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> processor, object asyncState = null, PhysicalBridge bridge = null)
{ {
var tcs = TaskSource.CreateDenyExecSync<T>(asyncState); var tcs = TaskSource.CreateDenyExecSync<T>(asyncState);
var source = ResultBox<T>.Get(tcs); var source = ResultBox<T>.Get(tcs);
message.SetSource(processor, source); message.SetSource(processor, source);
if (bridge == null) bridge = GetBridge(message.Command); if (bridge == null) bridge = GetBridge(message.Command);
if (!bridge.TryEnqueue(message, isSlave)) if (!bridge.TryEnqueue(message, isSlave))
{ {
ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this)); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this));
} }
return tcs.Task; return tcs.Task;
} }
internal void QueueDirectFireAndForget<T>(Message message, ResultProcessor<T> processor, PhysicalBridge bridge = null) internal void QueueDirectFireAndForget<T>(Message message, ResultProcessor<T> processor, PhysicalBridge bridge = null)
{ {
if (message != null) if (message != null)
{ {
message.SetSource(processor, null); message.SetSource(processor, null);
multiplexer.Trace("Enqueue: " + message); multiplexer.Trace("Enqueue: " + message);
(bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave); (bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave);
} }
} }
internal void ReportNextFailure() internal void ReportNextFailure()
{ {
var tmp = interactive; var tmp = interactive;
if (tmp != null) tmp.ReportNextFailure(); if (tmp != null) tmp.ReportNextFailure();
tmp = subscription; tmp = subscription;
if (tmp != null) tmp.ReportNextFailure(); if (tmp != null) tmp.ReportNextFailure();
} }
internal Task<bool> SendTracer(TextWriter log = null) internal Task<bool> SendTracer(TextWriter log = null)
{ {
var msg = GetTracerMessage(false); var msg = GetTracerMessage(false);
msg = LoggingMessage.Create(log, msg); msg = LoggingMessage.Create(log, msg);
return QueueDirectAsync(msg, ResultProcessor.Tracer); return QueueDirectAsync(msg, ResultProcessor.Tracer);
} }
internal string Summary() internal string Summary()
{ {
var sb = new StringBuilder(Format.ToString(endpoint)) var sb = new StringBuilder(Format.ToString(endpoint))
.Append(": ").Append(serverType).Append(" v").Append(version).Append(", ").Append(isSlave ? "slave" : "master"); .Append(": ").Append(serverType).Append(" v").Append(version).Append(", ").Append(isSlave ? "slave" : "master");
if (databases > 0) sb.Append("; ").Append(databases).Append(" databases"); if (databases > 0) sb.Append("; ").Append(databases).Append(" databases");
if (writeEverySeconds > 0) if (writeEverySeconds > 0)
sb.Append("; keep-alive: ").Append(TimeSpan.FromSeconds(writeEverySeconds)); sb.Append("; keep-alive: ").Append(TimeSpan.FromSeconds(writeEverySeconds));
var tmp = interactive; var tmp = interactive;
sb.Append("; int: ").Append(tmp == null ? "n/a" : tmp.ConnectionState.ToString()); sb.Append("; int: ").Append(tmp == null ? "n/a" : tmp.ConnectionState.ToString());
tmp = subscription; tmp = subscription;
if(tmp == null) if(tmp == null)
{ {
sb.Append("; sub: n/a"); sb.Append("; sub: n/a");
} else } else
{ {
var state = tmp.ConnectionState; var state = tmp.ConnectionState;
sb.Append("; sub: ").Append(state); sb.Append("; sub: ").Append(state);
if(state == PhysicalBridge.State.ConnectedEstablished) if(state == PhysicalBridge.State.ConnectedEstablished)
{ {
sb.Append(", ").Append(tmp.SubscriptionCount).Append(" active"); sb.Append(", ").Append(tmp.SubscriptionCount).Append(" active");
} }
} }
var flags = unselectableReasons; var flags = unselectableReasons;
if (flags != 0) if (flags != 0)
{ {
sb.Append("; not in use: ").Append(flags); sb.Append("; not in use: ").Append(flags);
} }
return sb.ToString(); return sb.ToString();
} }
internal void WriteDirectOrQueueFireAndForget<T>(PhysicalConnection connection, Message message, ResultProcessor<T> processor) internal void WriteDirectOrQueueFireAndForget<T>(PhysicalConnection connection, Message message, ResultProcessor<T> processor)
{ {
if (message != null) if (message != null)
{ {
message.SetSource(processor, null); message.SetSource(processor, null);
if (connection == null) if (connection == null)
{ {
multiplexer.Trace("Enqueue: " + message); multiplexer.Trace("Enqueue: " + message);
GetBridge(message.Command).TryEnqueue(message, isSlave); GetBridge(message.Command).TryEnqueue(message, isSlave);
} }
else else
{ {
multiplexer.Trace("Writing direct: " + message); multiplexer.Trace("Writing direct: " + message);
connection.Bridge.WriteMessageDirect(connection, message); connection.Bridge.WriteMessageDirect(connection, message);
} }
} }
} }
private PhysicalBridge CreateBridge(ConnectionType type, TextWriter log) private PhysicalBridge CreateBridge(ConnectionType type, TextWriter log)
{ {
multiplexer.Trace(type.ToString()); multiplexer.Trace(type.ToString());
var bridge = new PhysicalBridge(this, type); var bridge = new PhysicalBridge(this, type);
bridge.TryConnect(log); bridge.TryConnect(log);
return bridge; return bridge;
} }
void Handshake(PhysicalConnection connection, TextWriter log) void Handshake(PhysicalConnection connection, TextWriter log)
{ {
multiplexer.LogLocked(log, "Server handshake"); multiplexer.LogLocked(log, "Server handshake");
if (connection == null) if (connection == null)
{ {
multiplexer.Trace("No connection!?"); multiplexer.Trace("No connection!?");
return; return;
} }
Message msg; Message msg;
string password = multiplexer.RawConfig.Password; string password = multiplexer.RawConfig.Password;
if (!string.IsNullOrWhiteSpace(password)) if (!string.IsNullOrWhiteSpace(password))
{ {
multiplexer.LogLocked(log, "Authenticating (password)"); multiplexer.LogLocked(log, "Authenticating (password)");
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.AUTH, (RedisValue)password); msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.AUTH, (RedisValue)password);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK);
} }
if (multiplexer.CommandMap.IsAvailable(RedisCommand.CLIENT)) if (multiplexer.CommandMap.IsAvailable(RedisCommand.CLIENT))
{ {
string name = multiplexer.ClientName; string name = multiplexer.ClientName;
if (!string.IsNullOrWhiteSpace(name)) if (!string.IsNullOrWhiteSpace(name))
{ {
name = nameSanitizer.Replace(name, ""); name = nameSanitizer.Replace(name, "");
if (!string.IsNullOrWhiteSpace(name)) if (!string.IsNullOrWhiteSpace(name))
{ {
multiplexer.LogLocked(log, "Setting client name: {0}", name); multiplexer.LogLocked(log, "Setting client name: {0}", name);
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT, RedisLiterals.SETNAME, (RedisValue)name); msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT, RedisLiterals.SETNAME, (RedisValue)name);
msg.SetInternalCall(); msg.SetInternalCall();
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK);
} }
} }
} }
var connType = connection.Bridge.ConnectionType; var connType = connection.Bridge.ConnectionType;
if (connType == ConnectionType.Interactive) if (connType == ConnectionType.Interactive)
{ {
multiplexer.LogLocked(log, "Auto-configure..."); multiplexer.LogLocked(log, "Auto-configure...");
AutoConfigure(connection); AutoConfigure(connection);
} }
multiplexer.LogLocked(log, "Sending critical tracer: {0}", connection.Bridge); multiplexer.LogLocked(log, "Sending critical tracer: {0}", connection.Bridge);
var tracer = GetTracerMessage(true); var tracer = GetTracerMessage(true);
tracer = LoggingMessage.Create(log, tracer); tracer = LoggingMessage.Create(log, tracer);
WriteDirectOrQueueFireAndForget(connection, tracer, ResultProcessor.EstablishConnection); WriteDirectOrQueueFireAndForget(connection, tracer, ResultProcessor.EstablishConnection);
// note: this **must** be the last thing on the subscription handshake, because after this // note: this **must** be the last thing on the subscription handshake, because after this
// we will be in subscriber mode: regular commands cannot be sent // we will be in subscriber mode: regular commands cannot be sent
if (connType == ConnectionType.Subscription) if (connType == ConnectionType.Subscription)
{ {
var configChannel = multiplexer.ConfigurationChangedChannel; var configChannel = multiplexer.ConfigurationChangedChannel;
if(configChannel != null) if(configChannel != null)
{ {
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.SUBSCRIBE, (RedisChannel)configChannel); msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.SUBSCRIBE, (RedisChannel)configChannel);
WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.TrackSubscriptions); WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.TrackSubscriptions);
} }
} }
multiplexer.LogLocked(log, "Flushing outbound buffer"); multiplexer.LogLocked(log, "Flushing outbound buffer");
connection.Flush(); connection.Flush();
} }
private void SetConfig<T>(ref T field, T value, [CallerMemberName] string caller = null) private void SetConfig<T>(ref T field, T value, [CallerMemberName] string caller = null)
{ {
if(!EqualityComparer<T>.Default.Equals(field, value)) if(!EqualityComparer<T>.Default.Equals(field, value))
{ {
multiplexer.Trace(caller + " changed from " + field + " to " + value, "Configuration"); multiplexer.Trace(caller + " changed from " + field + " to " + value, "Configuration");
field = value; field = value;
multiplexer.ReconfigureIfNeeded(endpoint, false, caller); multiplexer.ReconfigureIfNeeded(endpoint, false, caller);
} }
} }
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
...@@ -126,7 +127,7 @@ public SocketManager(string name = null) ...@@ -126,7 +127,7 @@ public SocketManager(string name = null)
// we need a dedicated writer, because when under heavy ambient load // we need a dedicated writer, because when under heavy ambient load
// (a busy asp.net site, for example), workers are not reliable enough // (a busy asp.net site, for example), workers are not reliable enough
#if !DNXCORE50 #if !CORE_CLR
Thread dedicatedWriter = new Thread(writeAllQueues, 32 * 1024); // don't need a huge stack; Thread dedicatedWriter = new Thread(writeAllQueues, 32 * 1024); // don't need a huge stack;
dedicatedWriter.Priority = ThreadPriority.AboveNormal; // time critical dedicatedWriter.Priority = ThreadPriority.AboveNormal; // time critical
#else #else
...@@ -172,37 +173,56 @@ internal SocketToken BeginConnect(EndPoint endpoint, ISocketCallback callback, C ...@@ -172,37 +173,56 @@ internal SocketToken BeginConnect(EndPoint endpoint, ISocketCallback callback, C
this.ShouldForceConnectCompletionType(ref connectCompletionType); this.ShouldForceConnectCompletionType(ref connectCompletionType);
var formattedEndpoint = Format.ToString(endpoint); var formattedEndpoint = Format.ToString(endpoint);
var tuple = Tuple.Create(socket, callback);
if (endpoint is DnsEndPoint) if (endpoint is DnsEndPoint)
{ {
// A work-around for a Mono bug in BeginConnect(EndPoint endpoint, AsyncCallback callback, object state) // A work-around for a Mono bug in BeginConnect(EndPoint endpoint, AsyncCallback callback, object state)
DnsEndPoint dnsEndpoint = (DnsEndPoint)endpoint; DnsEndPoint dnsEndpoint = (DnsEndPoint)endpoint;
#if CORE_CLR
multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint);
socket.ConnectAsync(dnsEndpoint.Host, dnsEndpoint.Port).ContinueWith(t =>
{
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
EndConnectImpl(t, multiplexer, log, tuple);
multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint);
});
#else
CompletionTypeHelper.RunWithCompletionType( CompletionTypeHelper.RunWithCompletionType(
(cb) => (cb) => {
{
multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint);
return socket.BeginConnect(dnsEndpoint.Host, dnsEndpoint.Port, cb, Tuple.Create(socket, callback)); return socket.BeginConnect(dnsEndpoint.Host, dnsEndpoint.Port, cb, tuple);
}, },
(ar) => (ar) => {
{ multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); EndConnectImpl(ar, multiplexer, log, tuple);
EndConnectImpl(ar, multiplexer, log);
multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint); multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint);
}, },
connectCompletionType); connectCompletionType);
#endif
} }
else else
{ {
#if CORE_CLR
multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint);
socket.ConnectAsync(endpoint).ContinueWith(t =>
{
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
EndConnectImpl(t, multiplexer, log, tuple);
});
#else
CompletionTypeHelper.RunWithCompletionType( CompletionTypeHelper.RunWithCompletionType(
(cb) => { (cb) => {
multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint);
return socket.BeginConnect(endpoint, cb, Tuple.Create(socket, callback)); return socket.BeginConnect(endpoint, cb, tuple);
}, },
(ar) => { (ar) => {
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
EndConnectImpl(ar, multiplexer, log); EndConnectImpl(ar, multiplexer, log, tuple);
multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint); multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint);
}, },
connectCompletionType); connectCompletionType);
#endif
} }
} }
catch (NotImplementedException ex) catch (NotImplementedException ex)
...@@ -221,9 +241,9 @@ internal void SetFastLoopbackOption(Socket socket) ...@@ -221,9 +241,9 @@ internal void SetFastLoopbackOption(Socket socket)
// SIO_LOOPBACK_FAST_PATH (http://msdn.microsoft.com/en-us/library/windows/desktop/jj841212%28v=vs.85%29.aspx) // SIO_LOOPBACK_FAST_PATH (http://msdn.microsoft.com/en-us/library/windows/desktop/jj841212%28v=vs.85%29.aspx)
// Speeds up localhost operations significantly. OK to apply to a socket that will not be hooked up to localhost, // Speeds up localhost operations significantly. OK to apply to a socket that will not be hooked up to localhost,
// or will be subject to WFP filtering. // or will be subject to WFP filtering.
#if !DNXCORE50
const int SIO_LOOPBACK_FAST_PATH = -1744830448; const int SIO_LOOPBACK_FAST_PATH = -1744830448;
#if !CORE_CLR
// windows only // windows only
if (Environment.OSVersion.Platform == PlatformID.Win32NT) if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{ {
...@@ -231,8 +251,11 @@ internal void SetFastLoopbackOption(Socket socket) ...@@ -231,8 +251,11 @@ internal void SetFastLoopbackOption(Socket socket)
var osVersion = Environment.OSVersion.Version; var osVersion = Environment.OSVersion.Version;
if (osVersion.Major > 6 || osVersion.Major == 6 && osVersion.Minor >= 2) if (osVersion.Major > 6 || osVersion.Major == 6 && osVersion.Minor >= 2)
{ {
byte[] optionInValue = BitConverter.GetBytes(1); #endif
byte[] optionInValue = BitConverter.GetBytes(1);
socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue, null); socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue, null);
#if !CORE_CLR
} }
} }
#endif #endif
...@@ -262,18 +285,20 @@ internal void Shutdown(SocketToken token) ...@@ -262,18 +285,20 @@ internal void Shutdown(SocketToken token)
Shutdown(token.Socket); Shutdown(token.Socket);
} }
private void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer, TextWriter log) private void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer, TextWriter log, Tuple<Socket, ISocketCallback> tuple)
{ {
Tuple<Socket, ISocketCallback> tuple = null;
try try
{ {
tuple = (Tuple<Socket, ISocketCallback>)ar.AsyncState;
bool ignoreConnect = false; bool ignoreConnect = false;
ShouldIgnoreConnect(tuple.Item2, ref ignoreConnect); ShouldIgnoreConnect(tuple.Item2, ref ignoreConnect);
if (ignoreConnect) return; if (ignoreConnect) return;
var socket = tuple.Item1; var socket = tuple.Item1;
var callback = tuple.Item2; var callback = tuple.Item2;
#if CORE_CLR
multiplexer.Wait((Task)ar); // make it explode if invalid (note: already complete at this point)
#else
socket.EndConnect(ar); socket.EndConnect(ar);
#endif
var netStream = new NetworkStream(socket, false); var netStream = new NetworkStream(socket, false);
var socketMode = callback == null ? SocketMode.Abort : callback.Connected(netStream, log); var socketMode = callback == null ? SocketMode.Abort : callback.Connected(netStream, log);
switch (socketMode) switch (socketMode)
...@@ -298,7 +323,7 @@ private void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer, ...@@ -298,7 +323,7 @@ private void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer,
break; break;
} }
} }
catch(ObjectDisposedException) catch (ObjectDisposedException)
{ {
multiplexer.LogLocked(log, "(socket shutdown)"); multiplexer.LogLocked(log, "(socket shutdown)");
if (tuple != null) if (tuple != null)
...@@ -340,7 +365,7 @@ private void Shutdown(Socket socket) ...@@ -340,7 +365,7 @@ private void Shutdown(Socket socket)
{ {
OnShutdown(socket); OnShutdown(socket);
try { socket.Shutdown(SocketShutdown.Both); } catch { } try { socket.Shutdown(SocketShutdown.Both); } catch { }
#if !DNXCORE50 #if !CORE_CLR
try { socket.Close(); } catch { } try { socket.Close(); } catch { }
#endif #endif
try { socket.Dispose(); } catch { } try { socket.Dispose(); } catch { }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
/// <summary> /// <summary>
/// Describes a sorted-set element with the corresponding value /// Describes a sorted-set element with the corresponding value
/// </summary> /// </summary>
public struct SortedSetEntry : IEquatable<SortedSetEntry>, IComparable, IComparable<SortedSetEntry> public struct SortedSetEntry : IEquatable<SortedSetEntry>, IComparable, IComparable<SortedSetEntry>
{ {
internal readonly RedisValue element; internal readonly RedisValue element;
internal readonly double score; internal readonly double score;
/// <summary> /// <summary>
/// Initializes a SortedSetEntry value /// Initializes a SortedSetEntry value
/// </summary> /// </summary>
public SortedSetEntry(RedisValue element, double score) public SortedSetEntry(RedisValue element, double score)
{ {
this.element = element; this.element = element;
this.score = score; this.score = score;
} }
/// <summary> /// <summary>
/// The unique element stored in the sorted set /// The unique element stored in the sorted set
/// </summary> /// </summary>
public RedisValue Element { get { return element; } } public RedisValue Element { get { return element; } }
/// <summary> /// <summary>
/// The score against the element /// The score against the element
/// </summary> /// </summary>
public double Score { get { return score; } } public double Score { get { return score; } }
/// <summary> /// <summary>
/// The score against the element /// The score against the element
/// </summary> /// </summary>
#if !DNXCORE50 #if !CORE_CLR
[Browsable(false)] [Browsable(false)]
#endif #endif
[EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)]
public double Value { get { return score; } } public double Value { get { return score; } }
/// <summary> /// <summary>
/// The unique element stored in the sorted set /// The unique element stored in the sorted set
/// </summary> /// </summary>
#if !DNXCORE50 #if !CORE_CLR
[Browsable(false)] [Browsable(false)]
#endif #endif
[EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)] [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)]
public RedisValue Key { get { return element; } } public RedisValue Key { get { return element; } }
/// <summary> /// <summary>
/// Converts to a key/value pair /// Converts to a key/value pair
/// </summary> /// </summary>
public static implicit operator KeyValuePair<RedisValue,double>(SortedSetEntry value) public static implicit operator KeyValuePair<RedisValue,double>(SortedSetEntry value)
{ {
return new KeyValuePair<RedisValue, double>(value.element, value.score); return new KeyValuePair<RedisValue, double>(value.element, value.score);
} }
/// <summary> /// <summary>
/// Converts from a key/value pair /// Converts from a key/value pair
/// </summary> /// </summary>
public static implicit operator SortedSetEntry(KeyValuePair<RedisValue, double> value) public static implicit operator SortedSetEntry(KeyValuePair<RedisValue, double> value)
{ {
return new SortedSetEntry(value.Key, value.Value); return new SortedSetEntry(value.Key, value.Value);
} }
/// <summary> /// <summary>
/// See Object.ToString() /// See Object.ToString()
/// </summary> /// </summary>
public override string ToString() public override string ToString()
{ {
return element + ": " + score; return element + ": " + score;
} }
/// <summary> /// <summary>
/// See Object.GetHashCode() /// See Object.GetHashCode()
/// </summary> /// </summary>
public override int GetHashCode() public override int GetHashCode()
{ {
return element.GetHashCode() ^ score.GetHashCode(); return element.GetHashCode() ^ score.GetHashCode();
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return obj is SortedSetEntry && Equals((SortedSetEntry)obj); return obj is SortedSetEntry && Equals((SortedSetEntry)obj);
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public bool Equals(SortedSetEntry value) public bool Equals(SortedSetEntry value)
{ {
return this.score == value.score && this.element == value.element; return this.score == value.score && this.element == value.element;
} }
/// <summary> /// <summary>
/// Compares two values by score /// Compares two values by score
/// </summary> /// </summary>
public int CompareTo(SortedSetEntry value) public int CompareTo(SortedSetEntry value)
{ {
return this.score.CompareTo(value.score); return this.score.CompareTo(value.score);
} }
/// <summary> /// <summary>
/// Compares two values by score /// Compares two values by score
/// </summary> /// </summary>
public int CompareTo(object value) public int CompareTo(object value)
{ {
return value is SortedSetEntry ? CompareTo((SortedSetEntry)value) : -1; return value is SortedSetEntry ? CompareTo((SortedSetEntry)value) : -1;
} }
/// <summary> /// <summary>
/// Compares two values for equality /// Compares two values for equality
/// </summary> /// </summary>
public static bool operator ==(SortedSetEntry x, SortedSetEntry y) public static bool operator ==(SortedSetEntry x, SortedSetEntry y)
{ {
return x.score == y.score && x.element == y.element; return x.score == y.score && x.element == y.element;
} }
/// <summary> /// <summary>
/// Compares two values for non-equality /// Compares two values for non-equality
/// </summary> /// </summary>
public static bool operator !=(SortedSetEntry x, SortedSetEntry y) public static bool operator !=(SortedSetEntry x, SortedSetEntry y)
{ {
return x.score != y.score || x.element != y.element; return x.score != y.score || x.element != y.element;
} }
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
Copyright © 2002-2013 Charlie Poole
Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
Copyright © 2000-2002 Philip A. Craig
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required.
Portions Copyright © 2002-2013 Charlie Poole or Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\..\StackExchange.Redis.Tests\packages.config" />
</repositories>
\ No newline at end of file
{
"version": "1.1.0-alpha1",
"description": "High performance Redis client, incorporating both synchronous and asynchronous usage.",
"authors": [ "Stack Exchange inc., marc.gravell" ],
"owners": [ "marc.gravell" ],
"tags": [ "Async", "Redis", "Cache", "PubSub", "Messaging" ],
"projectUrl": "https://github.com/StackExchange/StackExchange.Redis",
"licenseUrl": "https://raw.github.com/StackExchange/StackExchange.Redis/master/LICENSE",
"copyright": "Stack Exchange inc. 2014-",
"requireLicenseAcceptance": false,
"summary": "Redis client library",
"dependencies": {
},
"compilationOptions": {
"allowUnsafe": true
},
"frameworks": {
"net40": {
"dependencies": {
"Microsoft.Bcl": "1.1.10",
"Microsoft.Bcl.Async": "1.0.168"
}
},
"net45": {
"frameworkAssemblies": {
"System.IO.Compression": "4.0.0.0"
}
},
"net46": {
"frameworkAssemblies": {
"System.IO.Compression": "4.0.0.0"
},
"define": [ "PLAT_SAFE_CONTINUATIONS" ]
},
"dnxcore50": {
"compilationOptions": {
"define": [ "PLAT_SAFE_CONTINUATIONS", "CORE_CLR" ]
},
"dependencies": {
"System.Collections.Concurrent": "4.0.11-beta-23516",
"System.Collections.NonGeneric": "4.0.1-beta-23516",
"System.Diagnostics.Debug": "4.0.11-beta-23516",
"System.Diagnostics.Tools": "4.0.1-beta-23516",
"System.Diagnostics.TraceSource": "4.0.0-beta-23516",
"System.Globalization": "4.0.11-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.IO.Compression": "4.1.0-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Net.NameResolution": "4.0.0-beta-23516",
"System.Net.Primitives": "4.0.11-beta-23516",
"System.Net.Security": "4.0.0-beta-23516",
"System.Net.Sockets": "4.1.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Reflection.Emit": "4.0.1-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.Reflection.Primitives": "4.0.1-beta-23516",
"System.Reflection.TypeExtensions": "4.1.0-beta-23516",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
"System.Security.Cryptography.X509Certificates": "4.0.0-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516",
"System.Threading.Thread": "4.0.0-beta-23516",
"System.Threading.ThreadPool": "4.0.10-beta-23516",
"System.Threading.Timer": "4.0.1-beta-23516"
}
},
"dotnet5.5": {
"compilationOptions": {
"define": [ "PLAT_SAFE_CONTINUATIONS", "CORE_CLR" ]
},
"dependencies": {
"System.Collections.Concurrent": "4.0.11-beta-23516",
"System.Collections.NonGeneric": "4.0.1-beta-23516",
"System.Diagnostics.Debug": "4.0.11-beta-23516",
"System.Diagnostics.Tools": "4.0.1-beta-23516",
"System.Diagnostics.TraceSource": "4.0.0-beta-23516",
"System.Globalization": "4.0.11-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.IO.Compression": "4.1.0-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Net.NameResolution": "4.0.0-beta-23516",
"System.Net.Primitives": "4.0.11-beta-23516",
"System.Net.Security": "4.0.0-beta-23516",
"System.Net.Sockets": "4.1.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Reflection.Emit": "4.0.1-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.Reflection.Primitives": "4.0.1-beta-23516",
"System.Reflection.TypeExtensions": "4.1.0-beta-23516",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
"System.Security.Cryptography.X509Certificates": "4.0.0-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516",
"System.Threading.Thread": "4.0.0-beta-23516",
"System.Threading.ThreadPool": "4.0.10-beta-23516",
"System.Threading.Timer": "4.0.1-beta-23516"
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{75CED009-AAC6-4AC1-9C38-A0530619062D}</ProjectGuid> <ProjectGuid>{75CED009-AAC6-4AC1-9C38-A0530619062D}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>StackExchange.Redis</RootNamespace> <RootNamespace>StackExchange.Redis</RootNamespace>
<AssemblyName>StackExchange.Redis.StrongName</AssemblyName> <AssemblyName>StackExchange.Redis.StrongName</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin.snk\Debug\</OutputPath> <OutputPath>bin.snk\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;NET40 STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;NET40 STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<DocumentationFile>bin.snk\Debug\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Debug\StackExchange.Redis.StrongName.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin.snk\Release\</OutputPath> <OutputPath>bin.snk\Release\</OutputPath>
<DefineConstants>TRACE;NET40 STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;NET40 STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<AssemblyOriginatorKeyFile>StackExchange.Redis.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\StackExchange.Redis.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
<DefineConstants>TRACE;NET40 STRONG_NAME FEATURE_SERIALIZATION</DefineConstants> <DefineConstants>TRACE;NET40 STRONG_NAME FEATURE_SERIALIZATION</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Threading.Tasks"> <Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions"> <Reference Include="Microsoft.Threading.Tasks.Extensions">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop"> <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO"> <Reference Include="System.IO">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="System.Runtime"> <Reference Include="System.Runtime">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Threading.Tasks"> <Reference Include="System.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\StackExchange.Redis\Properties\AssemblyInfo.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Aggregate.cs" /> </ItemGroup>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Bitwise.cs" /> <ItemGroup>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientFlags.cs" /> <None Include="packages.config" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientInfo.cs" /> </ItemGroup>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientType.cs"> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Link>ClientType.cs</Link> <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
</Compile> <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Compat\VolatileWrapper.cs"> <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Link>VolatileWrapper.cs</Link> <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Compile> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConcurrentProfileStorageCollection.cs" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.Profiling.cs"> Other similar extension points exist, see Microsoft.Common.targets.
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon> <Target Name="BeforeBuild">
</Compile> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClusterConfiguration.cs" /> <Target Name="AfterBuild">
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandFlags.cs" /> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandMap.cs" /> -->
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandTrace.cs" /> </Project>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletionManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Condition.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Exclude.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExportOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Format.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ICompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IProfiler.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedis.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ISubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ITransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Message.cs" />
<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\ProfileContextTracker.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ProfileStorage.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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RawResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisChannel.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisCommand.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisKey.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisValue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ReplicationChangeOptions.cs" />
<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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerSelectionStrategy.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SetOperation.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.NoPoll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.Poll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="StackExchange.Redis.snk" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}</ProjectGuid> <ProjectGuid>{36CAC6B6-2B88-447F-AA35-D4DAA5E4F2C7}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>StackExchange.Redis</RootNamespace> <RootNamespace>StackExchange.Redis</RootNamespace>
<AssemblyName>StackExchange.Redis</AssemblyName> <AssemblyName>StackExchange.Redis</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;NET40 FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;NET40 FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<DocumentationFile>bin\Debug\StackExchange.Redis.XML</DocumentationFile> <DocumentationFile>bin\Debug\StackExchange.Redis.XML</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath> <OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NET40 FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;NET40 FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
<DefineConstants>TRACE;NET40 FEATURE_SERIALIZATION</DefineConstants> <DefineConstants>TRACE;NET40 FEATURE_SERIALIZATION</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Threading.Tasks"> <Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions"> <Reference Include="Microsoft.Threading.Tasks.Extensions">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop"> <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.IO, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="System.Runtime, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Runtime, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Threading.Tasks, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Threading.Tasks, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\StackExchange.Redis\Properties\AssemblyInfo.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Aggregate.cs" /> </ItemGroup>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Bitwise.cs" /> <ItemGroup>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientFlags.cs" /> <None Include="app.config" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientInfo.cs" /> <None Include="packages.config" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientType.cs"> </ItemGroup>
<Link>ClientType.cs</Link> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Compile> <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Compat\VolatileWrapper.cs"> <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Link>VolatileWrapper.cs</Link> <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
</Compile> <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConcurrentProfileStorageCollection.cs" /> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.Profiling.cs"> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon> Other similar extension points exist, see Microsoft.Common.targets.
</Compile> <Target Name="BeforeBuild">
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClusterConfiguration.cs" /> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandFlags.cs" /> <Target Name="AfterBuild">
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandMap.cs" /> </Target>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandTrace.cs" /> -->
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletedDefaultTask.cs" /> </Project>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletionManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Condition.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Exclude.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExportOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Format.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ICompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IProfiler.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedis.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ISubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ITransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Message.cs" />
<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\ProfileContextTracker.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ProfileStorage.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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RawResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisChannel.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisCommand.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisKey.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisValue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ReplicationChangeOptions.cs" />
<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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerSelectionStrategy.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SetOperation.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.NoPoll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.Poll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EBF46088-E318-4D32-9EFB-01EF130A4554}</ProjectGuid> <ProjectGuid>{EBF46088-E318-4D32-9EFB-01EF130A4554}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>StackExchange.Redis</RootNamespace> <RootNamespace>StackExchange.Redis</RootNamespace>
<AssemblyName>StackExchange.Redis.StrongName</AssemblyName> <AssemblyName>StackExchange.Redis.StrongName</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin.snk\Debug\</OutputPath> <OutputPath>bin.snk\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Debug\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Debug\StackExchange.Redis.StrongName.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin.snk\Release\</OutputPath> <OutputPath>bin.snk\Release\</OutputPath>
<DefineConstants>TRACE;STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin.snk\Verbose\</OutputPath> <OutputPath>bin.snk\Verbose\</OutputPath>
<DefineConstants>TRACE;DEBUG;VERBOSE STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;VERBOSE STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Verbose\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Verbose\StackExchange.Redis.StrongName.xml</DocumentationFile>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin.snk\LogOutput\</OutputPath> <OutputPath>bin.snk\LogOutput\</OutputPath>
<DefineConstants>TRACE;DEBUG;LOGOUTPUT STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;LOGOUTPUT STRONG_NAME FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\LogOutput\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\LogOutput\StackExchange.Redis.StrongName.xml</DocumentationFile>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<AssemblyOriginatorKeyFile>StackExchange.Redis.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\StackExchange.Redis.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
<DefineConstants>TRACE;STRONG_NAME FEATURE_SERIALIZATION</DefineConstants> <DefineConstants>TRACE;STRONG_NAME FEATURE_SERIALIZATION</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile> <DocumentationFile>bin.snk\Release\StackExchange.Redis.StrongName.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="StackExchange\Redis\Aggregate.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="StackExchange\Redis\ClientType.cs" /> </ItemGroup>
<Compile Include="StackExchange\Redis\Compat\VolatileWrapper.cs" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Compile Include="StackExchange\Redis\ConcurrentProfileStorageCollection.cs" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.Profiling.cs"> Other similar extension points exist, see Microsoft.Common.targets.
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon> <Target Name="BeforeBuild">
</Compile> </Target>
<Compile Include="StackExchange\Redis\ExtensionMethods.cs" /> <Target Name="AfterBuild">
<Compile Include="StackExchange\Redis\HashEntry.cs" /> </Target>
<Compile Include="StackExchange\Redis\IConnectionMultiplexer.cs" /> -->
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" /> </Project>
<Compile Include="StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="StackExchange\Redis\IProfiler.cs" />
<Compile Include="StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="StackExchange\Redis\ProfileContextTracker.cs" />
<Compile Include="StackExchange\Redis\ProfileStorage.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" />
<Compile Include="StackExchange\Redis\ClientInfo.cs" />
<Compile Include="StackExchange\Redis\ClusterConfiguration.cs" />
<Compile Include="StackExchange\Redis\CommandTrace.cs" />
<Compile Include="StackExchange\Redis\Condition.cs" />
<Compile Include="StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs">
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon>
</Compile>
<Compile Include="StackExchange\Redis\ConnectionType.cs" />
<Compile Include="StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="StackExchange\Redis\Exclude.cs" />
<Compile Include="StackExchange\Redis\ExportOptions.cs" />
<Compile Include="StackExchange\Redis\Format.cs" />
<Compile Include="StackExchange\Redis\IBatch.cs" />
<Compile Include="StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="StackExchange\Redis\Order.cs" />
<Compile Include="StackExchange\Redis\RedisBatch.cs" />
<Compile Include="StackExchange\Redis\RedisCommand.cs" />
<Compile Include="StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="StackExchange\Redis\ITransaction.cs" />
<Compile Include="StackExchange\Redis\IRedis.cs" />
<Compile Include="StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="StackExchange\Redis\IDatabase.cs" />
<Compile Include="StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="StackExchange\Redis\IServer.cs" />
<Compile Include="StackExchange\Redis\ISubscriber.cs" />
<Compile Include="StackExchange\Redis\MessageCompletable.cs" />
<Compile Include="StackExchange\Redis\RedisBase.cs" />
<Compile Include="StackExchange\Redis\CommandFlags.cs" />
<Compile Include="StackExchange\Redis\CommandMap.cs" />
<Compile Include="StackExchange\Redis\CompletionManager.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="StackExchange\Redis\ICompletable.cs" />
<Compile Include="StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="StackExchange\Redis\PhysicalBridge.cs" />
<Compile Include="StackExchange\Redis\Message.cs" />
<Compile Include="StackExchange\Redis\MessageQueue.cs" />
<Compile Include="StackExchange\Redis\PhysicalConnection.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StackExchange\Redis\RedisResult.cs" />
<Compile Include="StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="StackExchange\Redis\RedisKey.cs" />
<Compile Include="StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="StackExchange\Redis\RedisServer.cs" />
<Compile Include="StackExchange\Redis\RedisType.cs" />
<Compile Include="StackExchange\Redis\RedisValue.cs" />
<Compile Include="StackExchange\Redis\ReplicationChangeOptions.cs" />
<Compile Include="StackExchange\Redis\RawResult.cs" />
<Compile Include="StackExchange\Redis\ResultBox.cs" />
<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" />
<Compile Include="StackExchange\Redis\ServerType.cs" />
<Compile Include="StackExchange\Redis\SetOperation.cs" />
<Compile Include="StackExchange\Redis\SocketManager.cs" />
<Compile Include="StackExchange\Redis\SocketManager.NoPoll.cs">
<DependentUpon>SocketManager.cs</DependentUpon>
</Compile>
<Compile Include="StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="StackExchange\Redis\SortType.cs" />
<Compile Include="StackExchange\Redis\StringSplits.cs" />
<Compile Include="StackExchange\Redis\TaskSource.cs" />
<Compile Include="StackExchange\Redis\When.cs" />
<Compile Include="StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="StackExchange\Redis\SaveType.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="StackExchange\Redis\SocketManager.Poll.cs">
<DependentUpon>SocketManager.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="StackExchange.Redis.snk" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7CEC07F2-8C03-4C42-B048-738B215824C1}</ProjectGuid> <ProjectGuid>{7CEC07F2-8C03-4C42-B048-738B215824C1}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>StackExchange.Redis</RootNamespace> <RootNamespace>StackExchange.Redis</RootNamespace>
<AssemblyName>StackExchange.Redis</AssemblyName> <AssemblyName>StackExchange.Redis</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Debug\StackExchange.Redis.XML</DocumentationFile> <DocumentationFile>bin\Debug\StackExchange.Redis.XML</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath> <OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Verbose|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Verbose\</OutputPath> <OutputPath>bin\Verbose\</OutputPath>
<DefineConstants>TRACE;DEBUG;VERBOSE;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;VERBOSE;FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Debug\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Debug\StackExchange.Redis.xml</DocumentationFile>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Log Output|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Log Output\</OutputPath> <OutputPath>bin\Log Output\</OutputPath>
<DefineConstants>TRACE;DEBUG;LOGOUTPUT FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants> <DefineConstants>TRACE;DEBUG;LOGOUTPUT FEATURE_SERIALIZATION FEATURE_SOCKET_MODE_POLL</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Debug\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Debug\StackExchange.Redis.xml</DocumentationFile>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
<DefineConstants>TRACE;__MonoCS__ FEATURE_SERIALIZATION</DefineConstants> <DefineConstants>TRACE;__MonoCS__ FEATURE_SERIALIZATION</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile> <DocumentationFile>bin\Release\StackExchange.Redis.xml</DocumentationFile>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="StackExchange\Redis\Aggregate.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="StackExchange\Redis\ClientType.cs" /> </ItemGroup>
<Compile Include="StackExchange\Redis\Compat\VolatileWrapper.cs" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Compile Include="StackExchange\Redis\ConcurrentProfileStorageCollection.cs" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.Profiling.cs"> Other similar extension points exist, see Microsoft.Common.targets.
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon> <Target Name="BeforeBuild">
</Compile> </Target>
<Compile Include="StackExchange\Redis\ExtensionMethods.cs" /> <Target Name="AfterBuild">
<Compile Include="StackExchange\Redis\HashEntry.cs" /> </Target>
<Compile Include="StackExchange\Redis\IConnectionMultiplexer.cs" /> -->
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="StackExchange\Redis\IProfiler.cs" />
<Compile Include="StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="StackExchange\Redis\ProfileContextTracker.cs" />
<Compile Include="StackExchange\Redis\ProfileStorage.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" />
<Compile Include="StackExchange\Redis\ClientInfo.cs" />
<Compile Include="StackExchange\Redis\ClusterConfiguration.cs" />
<Compile Include="StackExchange\Redis\CommandTrace.cs" />
<Compile Include="StackExchange\Redis\Condition.cs" />
<Compile Include="StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs">
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon>
</Compile>
<Compile Include="StackExchange\Redis\ConnectionType.cs" />
<Compile Include="StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="StackExchange\Redis\Exclude.cs" />
<Compile Include="StackExchange\Redis\ExportOptions.cs" />
<Compile Include="StackExchange\Redis\Format.cs" />
<Compile Include="StackExchange\Redis\IBatch.cs" />
<Compile Include="StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="StackExchange\Redis\Order.cs" />
<Compile Include="StackExchange\Redis\RedisBatch.cs" />
<Compile Include="StackExchange\Redis\RedisCommand.cs" />
<Compile Include="StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="StackExchange\Redis\ITransaction.cs" />
<Compile Include="StackExchange\Redis\IRedis.cs" />
<Compile Include="StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="StackExchange\Redis\IDatabase.cs" />
<Compile Include="StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="StackExchange\Redis\IServer.cs" />
<Compile Include="StackExchange\Redis\ISubscriber.cs" />
<Compile Include="StackExchange\Redis\MessageCompletable.cs" />
<Compile Include="StackExchange\Redis\RedisBase.cs" />
<Compile Include="StackExchange\Redis\CommandFlags.cs" />
<Compile Include="StackExchange\Redis\CommandMap.cs" />
<Compile Include="StackExchange\Redis\CompletionManager.cs" />
<Compile Include="StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="StackExchange\Redis\ICompletable.cs" />
<Compile Include="StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="StackExchange\Redis\PhysicalBridge.cs" />
<Compile Include="StackExchange\Redis\Message.cs" />
<Compile Include="StackExchange\Redis\MessageQueue.cs" />
<Compile Include="StackExchange\Redis\PhysicalConnection.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StackExchange\Redis\RedisResult.cs" />
<Compile Include="StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="StackExchange\Redis\RedisKey.cs" />
<Compile Include="StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="StackExchange\Redis\RedisServer.cs" />
<Compile Include="StackExchange\Redis\RedisType.cs" />
<Compile Include="StackExchange\Redis\RedisValue.cs" />
<Compile Include="StackExchange\Redis\ReplicationChangeOptions.cs" />
<Compile Include="StackExchange\Redis\RawResult.cs" />
<Compile Include="StackExchange\Redis\ResultBox.cs" />
<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" />
<Compile Include="StackExchange\Redis\ServerType.cs" />
<Compile Include="StackExchange\Redis\SetOperation.cs" />
<Compile Include="StackExchange\Redis\SocketManager.cs" />
<Compile Include="StackExchange\Redis\SocketManager.NoPoll.cs">
<DependentUpon>SocketManager.cs</DependentUpon>
</Compile>
<Compile Include="StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="StackExchange\Redis\SortType.cs" />
<Compile Include="StackExchange\Redis\StringSplits.cs" />
<Compile Include="StackExchange\Redis\TaskSource.cs" />
<Compile Include="StackExchange\Redis\When.cs" />
<Compile Include="StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="StackExchange\Redis\SaveType.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="StackExchange\Redis\SocketManager.Poll.cs">
<DependentUpon>SocketManager.cs</DependentUpon>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project> </Project>
\ No newline at end of file
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<AssemblyOriginatorKeyFile>StackExchange.Redis.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\StackExchange.Redis.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono|AnyCPU'">
<OutputPath>bin\Mono\</OutputPath> <OutputPath>bin\Mono\</OutputPath>
...@@ -62,116 +62,11 @@ ...@@ -62,116 +62,11 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\StackExchange.Redis\Properties\AssemblyInfo.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Aggregate.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Bitwise.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientFlags.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientInfo.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientType.cs">
<Link>ClientType.cs</Link>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Compat\VolatileWrapper.cs">
<Link>VolatileWrapper.cs</Link>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConcurrentProfileStorageCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.Profiling.cs">
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClusterConfiguration.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandFlags.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandMap.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandTrace.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletionManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Condition.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Exclude.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExportOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Format.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ICompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IProfiler.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedis.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ISubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ITransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Message.cs" />
<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\ProfileContextTracker.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ProfileStorage.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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RawResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisChannel.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisCommand.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisKey.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisValue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ReplicationChangeOptions.cs" />
<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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerSelectionStrategy.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SetOperation.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.NoPoll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.Poll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="StackExchange.Redis.snk" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" /> <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
......
...@@ -56,112 +56,8 @@ ...@@ -56,112 +56,8 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\StackExchange.Redis\Properties\AssemblyInfo.cs" /> <Compile Include="..\StackExchange.Redis\**\*.cs"/>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Aggregate.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Bitwise.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientFlags.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientInfo.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClientType.cs">
<Link>ClientType.cs</Link>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Compat\VolatileWrapper.cs">
<Link>VolatileWrapper.cs</Link>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConcurrentProfileStorageCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.Profiling.cs">
<DependentUpon>ConnectionMultiplexer.cs</DependentUpon>
</Compile>
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ClusterConfiguration.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandFlags.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandMap.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CommandTrace.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletedDefaultTask.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\CompletionManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Condition.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConfigurationOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionCounters.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionFailureType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.ReaderWriter.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ConnectionType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\DebuggingAids.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointCollection.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\EndPointEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExceptionFactory.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Exclude.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExportOptions.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Format.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\HashSlotMovedEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ICompletable.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IConnectionMultiplexer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IDatabaseAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IMultiMessage.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\InternalRegexCompiledOption.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IProfiler.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedis.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IRedisAsync.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\IServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ISubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ITransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\LoggingTextStream.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\Message.cs" />
<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\ProfileContextTracker.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ProfileStorage.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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RawResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisBatch.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisChannel.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisCommand.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisErrorEventArgs.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisFeatures.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisKey.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisLiterals.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisResult.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisServer.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisSubscriber.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisTransaction.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\RedisValue.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ReplicationChangeOptions.cs" />
<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" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerSelectionStrategy.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ServerType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SetOperation.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.NoPoll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SocketManager.Poll.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\SortType.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
......
{
"version": "1.1.0-*",
"description": "StackExchange.Redis",
"authors": [ "jeremymeng" ],
"tags": [ "" ],
"projectUrl": "",
"licenseUrl": "",
"compile": [
"../../StackExchange.Redis/**/*.cs"
],
"dependencies": {
},
"configurations": {
"Debug": {
"compilationOptions": {
"define": [ "DEBUG", "TRACE" ],
"allowUnsafe": true
}
},
"Release": {
"compilationOptions": {
"define": [ "TRACE" ],
"allowUnsafe": true
}
}
},
"frameworks": {
"dnxcore50": {
"dependencies": {
"System.Diagnostics.Debug": "4.0.0",
"System.Diagnostics.TraceSource": "4.0.0-beta-23409",
"System.Diagnostics.Tools": "4.0.0",
"System.IO.Compression": "4.0.0",
"System.Globalization": "4.0.10",
"System.Linq": "4.0.0",
"System.Net.Primitives": "4.0.10",
"System.Net.Sockets": "4.1.0-beta-23409",
"System.Net.Security": "4.0.0-beta-23409",
"System.Net.NameResolution": "4.0.0-beta-23409",
"System.Reflection": "4.0.0",
"System.Reflection.Emit": "4.0.0",
"System.Reflection.TypeExtensions": "4.0.0",
"System.Reflection.Primitives": "4.0.0",
"System.Reflection.Emit.Lightweight": "4.0.0",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23409",
"System.Security.Cryptography.X509Certificates": "4.0.0-beta-23409",
"System.Text.RegularExpressions": "4.0.10",
"System.Threading": "4.0.0",
"System.Threading.Thread": "4.0.0-*",
"System.Threading.ThreadPool": "4.0.10-beta-23409",
"System.Threading.Timer": "4.0.1-beta-23409",
"System.Threading.Tasks": "4.0.0"
}
}
}
}
\ No newline at end of file
{ {
"sdk": { "sdk": {
"version": "1.0.0-beta8", "version": "1.0.0-rc1-final",
"runtime": "coreclr", "runtime": "coreclr",
"architecture": "x86" "architecture": "x86"
}, },
......
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