Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
StackExchange.Redis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
StackExchange.Redis
Commits
9e878625
Commit
9e878625
authored
Jul 15, 2018
by
Marc Gravell
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pipelines' into async-timeout
parents
5183f1d4
76326ba6
Changes
46
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
730 additions
and
765 deletions
+730
-765
QueryTest.cs
NRediSearch.Test/QueryTest.cs
+11
-17
AdhocTests.cs
StackExchange.Redis.Tests/AdhocTests.cs
+1
-1
BasicOps.cs
StackExchange.Redis.Tests/BasicOps.cs
+26
-27
Bits.cs
StackExchange.Redis.Tests/Bits.cs
+1
-1
Cluster.cs
StackExchange.Redis.Tests/Cluster.cs
+7
-10
Constraints.cs
StackExchange.Redis.Tests/Constraints.cs
+7
-9
Databases.cs
StackExchange.Redis.Tests/Databases.cs
+12
-16
Expiry.cs
StackExchange.Redis.Tests/Expiry.cs
+13
-12
Failover.cs
StackExchange.Redis.Tests/Failover.cs
+4
-2
FloatingPoint.cs
StackExchange.Redis.Tests/FloatingPoint.cs
+2
-2
GeoTests.cs
StackExchange.Redis.Tests/GeoTests.cs
+12
-12
Hashes.cs
StackExchange.Redis.Tests/Hashes.cs
+85
-68
redis-sharp.cs
StackExchange.Redis.Tests/Helpers/redis-sharp.cs
+14
-14
SO10504853.cs
StackExchange.Redis.Tests/Issues/SO10504853.cs
+14
-11
SO10825542.cs
StackExchange.Redis.Tests/Issues/SO10825542.cs
+8
-8
SO24807536.cs
StackExchange.Redis.Tests/Issues/SO24807536.cs
+4
-4
SO25113323.cs
StackExchange.Redis.Tests/Issues/SO25113323.cs
+1
-2
Keys.cs
StackExchange.Redis.Tests/Keys.cs
+4
-4
Lex.cs
StackExchange.Redis.Tests/Lex.cs
+5
-6
Lists.cs
StackExchange.Redis.Tests/Lists.cs
+3
-3
Locking.cs
StackExchange.Redis.Tests/Locking.cs
+29
-56
MassiveOps.cs
StackExchange.Redis.Tests/MassiveOps.cs
+4
-4
Migrate.cs
StackExchange.Redis.Tests/Migrate.cs
+6
-5
MultiAdd.cs
StackExchange.Redis.Tests/MultiAdd.cs
+24
-24
Performance.cs
StackExchange.Redis.Tests/Performance.cs
+1
-1
PreserveOrder.cs
StackExchange.Redis.Tests/PreserveOrder.cs
+1
-1
Profiling.cs
StackExchange.Redis.Tests/Profiling.cs
+39
-30
PubSub.cs
StackExchange.Redis.Tests/PubSub.cs
+14
-23
SSDB.cs
StackExchange.Redis.Tests/SSDB.cs
+2
-2
SSL.cs
StackExchange.Redis.Tests/SSL.cs
+9
-12
Scans.cs
StackExchange.Redis.Tests/Scans.cs
+17
-17
Scripting.cs
StackExchange.Redis.Tests/Scripting.cs
+97
-110
Sets.cs
StackExchange.Redis.Tests/Sets.cs
+17
-18
Strings.cs
StackExchange.Redis.Tests/Strings.cs
+80
-79
TestBase.cs
StackExchange.Redis.Tests/TestBase.cs
+5
-18
Transactions.cs
StackExchange.Redis.Tests/Transactions.cs
+71
-71
WithKeyPrefixTests.cs
StackExchange.Redis.Tests/WithKeyPrefixTests.cs
+15
-12
CompletionManager.cs
StackExchange.Redis/StackExchange/Redis/CompletionManager.cs
+1
-1
ConfigurationOptions.cs
...xchange.Redis/StackExchange/Redis/ConfigurationOptions.cs
+7
-10
ConnectionMultiplexer.cs
...change.Redis/StackExchange/Redis/ConnectionMultiplexer.cs
+16
-10
WrapperBase.cs
...edis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs
+4
-4
PhysicalBridge.cs
StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs
+1
-1
PhysicalConnection.cs
...kExchange.Redis/StackExchange/Redis/PhysicalConnection.cs
+10
-5
RedisDatabase.cs
StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs
+13
-10
RedisTransaction.cs
StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs
+1
-1
RedisValue.cs
StackExchange.Redis/StackExchange/Redis/RedisValue.cs
+12
-11
No files found.
NRediSearch.Test/QueryTest.cs
View file @
9e878625
...
...
@@ -8,7 +8,7 @@ public class QueryTest
public
static
Query
GetQuery
()
=>
new
Query
(
"hello world"
);
[
Fact
]
public
void
g
etNoContent
()
public
void
G
etNoContent
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
NoContent
);
...
...
@@ -17,7 +17,7 @@ public void getNoContent()
}
[
Fact
]
public
void
g
etWithScores
()
public
void
G
etWithScores
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
WithScores
);
...
...
@@ -26,7 +26,7 @@ public void getWithScores()
}
[
Fact
]
public
void
s
erializeRedisArgs
()
public
void
S
erializeRedisArgs
()
{
var
query
=
new
Query
(
"hello world"
)
{
...
...
@@ -38,7 +38,6 @@ public void serializeRedisArgs()
WithScores
=
true
};
var
args
=
new
List
<
object
>();
query
.
SerializeRedisArgs
(
args
);
...
...
@@ -57,7 +56,7 @@ public void serializeRedisArgs()
}
[
Fact
]
public
void
l
imit
()
public
void
L
imit
()
{
var
query
=
GetQuery
();
Assert
.
Equal
(
0
,
query
.
_paging
.
Offset
);
...
...
@@ -65,11 +64,10 @@ public void limit()
Assert
.
Same
(
query
,
query
.
Limit
(
1
,
30
));
Assert
.
Equal
(
1
,
query
.
_paging
.
Offset
);
Assert
.
Equal
(
30
,
query
.
_paging
.
Count
);
}
[
Fact
]
public
void
a
ddFilter
()
public
void
A
ddFilter
()
{
var
query
=
GetQuery
();
Assert
.
Empty
(
query
.
_filters
);
...
...
@@ -79,7 +77,7 @@ public void addFilter()
}
[
Fact
]
public
void
s
etVerbatim
()
public
void
S
etVerbatim
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
Verbatim
);
...
...
@@ -87,20 +85,17 @@ public void setVerbatim()
Assert
.
True
(
query
.
Verbatim
);
}
[
Fact
]
public
void
s
etNoStopwords
()
public
void
S
etNoStopwords
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
NoStopwords
);
Assert
.
Same
(
query
,
query
.
SetNoStopwords
());
Assert
.
True
(
query
.
NoStopwords
);
}
[
Fact
]
public
void
s
etLanguage
()
public
void
S
etLanguage
()
{
var
query
=
GetQuery
();
Assert
.
Null
(
query
.
Language
);
...
...
@@ -109,17 +104,16 @@ public void setLanguage()
}
[
Fact
]
public
void
l
imitFields
()
public
void
L
imitFields
()
{
var
query
=
GetQuery
();
Assert
.
Null
(
query
.
_fields
);
Assert
.
Same
(
query
,
query
.
LimitFields
(
"foo"
,
"bar"
));
Assert
.
Equal
(
2
,
query
.
_fields
.
Length
);
}
[
Fact
]
public
void
h
ighlightFields
()
public
void
H
ighlightFields
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
_wantsHighlight
);
...
...
@@ -144,7 +138,7 @@ public void highlightFields()
}
[
Fact
]
public
void
s
ummarizeFields
()
public
void
S
ummarizeFields
()
{
var
query
=
GetQuery
();
Assert
.
False
(
query
.
_wantsSummarize
);
...
...
StackExchange.Redis.Tests/AdhocTests.cs
View file @
9e878625
...
...
@@ -17,7 +17,7 @@ public void TestAdhocCommandsAPI()
// needs explicit RedisKey type for key-based
// sharding to work; will still work with strings,
// but no key-based sharding support
RedisKey
key
=
"some_key"
;
RedisKey
key
=
Me
()
;
// note: if command renames are configured in
// the API, they will still work automatically
...
...
StackExchange.Redis.Tests/BasicOps.cs
View file @
9e878625
...
...
@@ -13,14 +13,13 @@ public class BasicOpsTests : TestBase
public
BasicOpsTests
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
[
Fact
]
public
void
PingOnce
()
public
async
Task
PingOnce
()
{
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
var
task
=
conn
.
PingAsync
();
var
duration
=
muxer
.
Wait
(
task
);
var
duration
=
await
conn
.
PingAsync
().
ForAwait
();
Log
(
"Ping took: "
+
duration
);
Assert
.
True
(
duration
.
TotalMilliseconds
>
0
);
}
...
...
@@ -33,7 +32,7 @@ public void RapidDispose()
using
(
var
primary
=
Create
())
{
var
conn
=
primary
.
GetDatabase
();
conn
.
KeyDelete
(
key
);
conn
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
...
...
@@ -47,18 +46,17 @@ public void RapidDispose()
}
[
Fact
]
public
void
PingMany
()
public
async
Task
PingMany
()
{
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
var
tasks
=
new
Task
<
TimeSpan
>[
100
];
for
(
int
i
=
0
;
i
<
tasks
.
Length
;
i
++)
{
tasks
[
i
]
=
conn
.
PingAsync
();
}
muxer
.
WaitAll
(
tasks
);
await
Task
.
WhenAll
(
tasks
).
ForAwait
(
);
Assert
.
True
(
tasks
[
0
].
Result
.
TotalMilliseconds
>
0
);
Assert
.
True
(
tasks
[
tasks
.
Length
-
1
].
Result
.
TotalMilliseconds
>
0
);
}
...
...
@@ -99,7 +97,7 @@ public void SetWithNullValue()
db
.
StringSet
(
key
,
"abc"
,
flags
:
CommandFlags
.
FireAndForget
);
Assert
.
True
(
db
.
KeyExists
(
key
));
db
.
StringSet
(
key
,
value
);
db
.
StringSet
(
key
,
value
,
flags
:
CommandFlags
.
FireAndForget
);
var
actual
=
(
string
)
db
.
StringGet
(
key
);
Assert
.
Null
(
actual
);
...
...
@@ -119,7 +117,7 @@ public void SetWithDefaultValue()
db
.
StringSet
(
key
,
"abc"
,
flags
:
CommandFlags
.
FireAndForget
);
Assert
.
True
(
db
.
KeyExists
(
key
));
db
.
StringSet
(
key
,
value
);
db
.
StringSet
(
key
,
value
,
flags
:
CommandFlags
.
FireAndForget
);
var
actual
=
(
string
)
db
.
StringGet
(
key
);
Assert
.
Null
(
actual
);
...
...
@@ -139,7 +137,7 @@ public void SetWithZeroValue()
db
.
StringSet
(
key
,
"abc"
,
flags
:
CommandFlags
.
FireAndForget
);
Assert
.
True
(
db
.
KeyExists
(
key
));
db
.
StringSet
(
key
,
value
);
db
.
StringSet
(
key
,
value
,
flags
:
CommandFlags
.
FireAndForget
);
var
actual
=
(
string
)
db
.
StringGet
(
key
);
Assert
.
Equal
(
"0"
,
actual
);
...
...
@@ -182,10 +180,10 @@ public void GetSetSync()
var
conn
=
muxer
.
GetDatabase
();
RedisKey
key
=
Me
();
conn
.
KeyDelete
(
key
);
conn
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
var
d1
=
conn
.
KeyDelete
(
key
);
var
g1
=
conn
.
StringGet
(
key
);
conn
.
StringSet
(
key
,
"123"
);
conn
.
StringSet
(
key
,
"123"
,
flags
:
CommandFlags
.
FireAndForget
);
var
g2
=
conn
.
StringGet
(
key
);
var
d2
=
conn
.
KeyDelete
(
key
);
...
...
@@ -204,23 +202,23 @@ public void GetSetSync()
[
InlineData
(
false
,
false
)]
[
InlineData
(
true
,
true
)]
[
InlineData
(
true
,
false
)]
public
void
GetWithExpiry
(
bool
exists
,
bool
hasExpiry
)
public
async
Task
GetWithExpiry
(
bool
exists
,
bool
hasExpiry
)
{
using
(
var
conn
=
Create
())
{
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
if
(
exists
)
{
if
(
hasExpiry
)
db
.
StringSet
(
key
,
"val"
,
TimeSpan
.
FromMinutes
(
5
));
db
.
StringSet
(
key
,
"val"
,
TimeSpan
.
FromMinutes
(
5
)
,
flags
:
CommandFlags
.
FireAndForget
);
else
db
.
StringSet
(
key
,
"val"
);
db
.
StringSet
(
key
,
"val"
,
flags
:
CommandFlags
.
FireAndForget
);
}
var
async
=
db
.
StringGetWithExpiryAsync
(
key
);
var
syncResult
=
db
.
StringGetWithExpiry
(
key
);
var
asyncResult
=
db
.
Wait
(
async
)
;
var
asyncResult
=
await
async
;
if
(
exists
)
{
...
...
@@ -248,8 +246,8 @@ public async Task GetWithExpiryWrongTypeAsync()
{
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
SetAdd
(
key
,
"abc"
);
var
del
=
db
.
KeyDeleteAsync
(
key
);
var
add
=
db
.
SetAddAsync
(
key
,
"abc"
);
var
ex
=
await
Assert
.
ThrowsAsync
<
RedisServerException
>(
async
()
=>
{
try
...
...
@@ -269,14 +267,14 @@ public async Task GetWithExpiryWrongTypeAsync()
[
Fact
]
public
void
GetWithExpiryWrongTypeSync
()
{
RedisKey
key
=
Me
();
var
ex
=
Assert
.
Throws
<
RedisServerException
>(()
=>
{
using
(
var
conn
=
Create
())
{
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
SetAdd
(
key
,
"abc"
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"abc"
,
CommandFlags
.
FireAndForget
);
db
.
StringGetWithExpiry
(
key
);
}
});
...
...
@@ -431,15 +429,16 @@ private void Incr(IDatabase database, RedisKey key, int delta, ref int total)
[
Fact
]
public
void
WrappedDatabasePrefixIntegration
()
{
var
key
=
Me
();
using
(
var
conn
=
Create
())
{
var
db
=
conn
.
GetDatabase
().
WithKeyPrefix
(
"abc"
);
db
.
KeyDelete
(
"count"
);
db
.
StringIncrement
(
"count"
);
db
.
StringIncrement
(
"count"
);
db
.
StringIncrement
(
"count"
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
db
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
db
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
int
count
=
(
int
)
conn
.
GetDatabase
().
StringGet
(
"abc
count"
);
int
count
=
(
int
)
conn
.
GetDatabase
().
StringGet
(
"abc
"
+
key
);
Assert
.
Equal
(
3
,
count
);
}
}
...
...
StackExchange.Redis.Tests/Bits.cs
View file @
9e878625
...
...
@@ -22,4 +22,4 @@ public void BasicOps()
}
}
}
}
\ No newline at end of file
}
StackExchange.Redis.Tests/Cluster.cs
View file @
9e878625
...
...
@@ -36,7 +36,7 @@ public void ExportConfiguration()
}
[
Fact
]
public
async
Task
ConnectUsesSingleSocket
()
public
void
ConnectUsesSingleSocket
()
{
using
(
var
sw
=
new
StringWriter
())
{
...
...
@@ -46,7 +46,6 @@ public async Task ConnectUsesSingleSocket()
{
using
(
var
muxer
=
Create
(
failMessage
:
i
+
": "
,
log
:
sw
))
{
await
Task
.
Delay
(
500
).
ForAwait
();
foreach
(
var
ep
in
muxer
.
GetEndPoints
())
{
var
srv
=
muxer
.
GetServer
(
ep
);
...
...
@@ -174,8 +173,8 @@ string StringGet(IServer server, RedisKey key, CommandFlags flags = CommandFlags
var
key
=
Me
();
const
string
value
=
"abc"
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
StringSet
(
key
,
value
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
StringSet
(
key
,
value
,
flags
:
CommandFlags
.
FireAndForget
);
servers
.
First
().
Ping
();
var
config
=
servers
.
First
().
ClusterConfiguration
;
Assert
.
NotNull
(
config
);
...
...
@@ -445,12 +444,12 @@ public void SScan()
{
RedisKey
key
=
"a"
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
int
totalUnfiltered
=
0
,
totalFiltered
=
0
;
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
totalUnfiltered
+=
i
;
if
(
i
.
ToString
().
Contains
(
"3"
))
totalFiltered
+=
i
;
}
...
...
@@ -502,7 +501,6 @@ public void AccessRandomKeys()
};
var
pairs
=
new
Dictionary
<
string
,
string
>();
const
int
COUNT
=
500
;
Task
[]
send
=
new
Task
[
COUNT
];
int
index
=
0
;
var
servers
=
conn
.
GetEndPoints
().
Select
(
x
=>
conn
.
GetServer
(
x
));
...
...
@@ -520,9 +518,8 @@ public void AccessRandomKeys()
var
key
=
Guid
.
NewGuid
().
ToString
();
var
value
=
Guid
.
NewGuid
().
ToString
();
pairs
.
Add
(
key
,
value
);
send
[
index
++]
=
cluster
.
StringSetAsync
(
key
,
value
);
cluster
.
StringSet
(
key
,
value
,
flags
:
CommandFlags
.
FireAndForget
);
}
conn
.
WaitAll
(
send
);
var
expected
=
new
string
[
COUNT
];
var
actual
=
new
Task
<
RedisValue
>[
COUNT
];
...
...
@@ -597,7 +594,7 @@ public void SimpleProfiling()
var
profiler
=
new
TestProfiler
();
var
key
=
Me
();
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
conn
.
RegisterProfiler
(
profiler
);
conn
.
BeginProfiling
(
profiler
.
MyContext
);
...
...
StackExchange.Redis.Tests/Constraints.cs
View file @
9e878625
...
...
@@ -17,32 +17,30 @@ public void ValueEquals()
}
[
Fact
]
public
void
TestManualIncr
()
public
async
Task
TestManualIncr
()
{
using
(
var
muxer
=
Create
(
syncTimeout
:
120000
))
// big timeout while debugging
{
var
key
=
Me
();
var
conn
=
muxer
.
GetDatabase
();
for
(
int
i
=
0
;
i
<
20
0
;
i
++)
for
(
int
i
=
0
;
i
<
1
0
;
i
++)
{
conn
.
KeyDelete
(
key
);
Assert
.
Equal
(
1
,
conn
.
Wait
(
ManualIncr
(
conn
,
key
)
));
Assert
.
Equal
(
2
,
conn
.
Wait
(
ManualIncr
(
conn
,
key
)
));
conn
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
Assert
.
Equal
(
1
,
await
ManualIncrAsync
(
conn
,
key
));
Assert
.
Equal
(
2
,
await
ManualIncrAsync
(
conn
,
key
));
Assert
.
Equal
(
2
,
(
long
)
conn
.
StringGet
(
key
));
}
}
}
public
async
Task
<
long
?>
ManualIncr
(
IDatabase
connection
,
RedisKey
key
)
public
async
Task
<
long
?>
ManualIncr
Async
(
IDatabase
connection
,
RedisKey
key
)
{
var
oldVal
=
(
long
?)
await
connection
.
StringGetAsync
(
key
).
ForAwait
();
var
newVal
=
(
oldVal
??
0
)
+
1
;
var
tran
=
connection
.
CreateTransaction
();
{
// check hasn't changed
#pragma warning disable 4014
tran
.
AddCondition
(
Condition
.
StringEqual
(
key
,
oldVal
));
tran
.
StringSetAsync
(
key
,
newVal
);
#pragma warning restore 4014
var
t
=
tran
.
StringSetAsync
(
key
,
newVal
);
if
(!
await
tran
.
ExecuteAsync
().
ForAwait
())
return
null
;
// aborted
return
newVal
;
}
...
...
StackExchange.Redis.Tests/Databases.cs
View file @
9e878625
...
...
@@ -26,11 +26,11 @@ public async Task CountKeys()
Skip
.
IfMissingDatabase
(
muxer
,
db1Id
);
Skip
.
IfMissingDatabase
(
muxer
,
db2Id
);
RedisKey
key
=
Me
();
var
db
61
=
muxer
.
GetDatabase
(
db1Id
);
var
db
62
=
muxer
.
GetDatabase
(
db2Id
);
db
61
.
StringSet
(
"abc"
,
"def"
,
flags
:
CommandFlags
.
FireAndForget
);
db
61
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
db
62
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
var
db
a
=
muxer
.
GetDatabase
(
db1Id
);
var
db
b
=
muxer
.
GetDatabase
(
db2Id
);
db
a
.
StringSet
(
"abc"
,
"def"
,
flags
:
CommandFlags
.
FireAndForget
);
db
a
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
db
b
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
var
server
=
GetAnyMaster
(
muxer
);
var
c0
=
server
.
DatabaseSizeAsync
(
db1Id
);
...
...
@@ -56,7 +56,7 @@ public void DatabaseCount()
}
[
Fact
]
public
void
MultiDatabases
()
public
async
Task
MultiDatabases
()
{
using
(
var
muxer
=
Create
())
{
...
...
@@ -64,26 +64,22 @@ public void MultiDatabases()
var
db0
=
muxer
.
GetDatabase
(
TestConfig
.
GetDedicatedDB
(
muxer
));
var
db1
=
muxer
.
GetDatabase
(
TestConfig
.
GetDedicatedDB
(
muxer
));
var
db2
=
muxer
.
GetDatabase
(
TestConfig
.
GetDedicatedDB
(
muxer
));
db0
.
Ping
();
db0
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db1
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db2
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
muxer
.
WaitAll
(
db0
.
StringSetAsync
(
key
,
"a"
),
db1
.
StringSetAsync
(
key
,
"b"
),
db2
.
StringSetAsync
(
key
,
"c"
)
);
db0
.
StringSet
(
key
,
"a"
,
flags
:
CommandFlags
.
FireAndForget
);
db1
.
StringSet
(
key
,
"b"
,
flags
:
CommandFlags
.
FireAndForget
);
db2
.
StringSet
(
key
,
"c"
,
flags
:
CommandFlags
.
FireAndForget
);
var
a
=
db0
.
StringGetAsync
(
key
);
var
b
=
db1
.
StringGetAsync
(
key
);
var
c
=
db2
.
StringGetAsync
(
key
);
muxer
.
WaitAll
(
a
,
b
,
c
);
Assert
.
Equal
(
"a"
,
muxer
.
Wait
(
a
)
);
// db:0
Assert
.
Equal
(
"b"
,
muxer
.
Wait
(
b
)
);
// db:1
Assert
.
Equal
(
"c"
,
muxer
.
Wait
(
c
)
);
// db:2
Assert
.
Equal
(
"a"
,
await
a
);
// db:0
Assert
.
Equal
(
"b"
,
await
b
);
// db:1
Assert
.
Equal
(
"c"
,
await
c
);
// db:2
}
}
}
...
...
StackExchange.Redis.Tests/Expiry.cs
View file @
9e878625
using
System
;
using
System.Threading.Tasks
;
using
Xunit
;
using
Xunit.Abstractions
;
...
...
@@ -13,7 +14,7 @@ public class Expiry : TestBase
[
Theory
]
[
InlineData
(
true
)]
[
InlineData
(
false
)]
public
void
TestBasicExpiryTimeSpan
(
bool
disablePTimes
)
public
async
Task
TestBasicExpiryTimeSpan
(
bool
disablePTimes
)
{
using
(
var
muxer
=
Create
(
disabledCommands
:
GetMap
(
disablePTimes
)))
{
...
...
@@ -32,15 +33,15 @@ public void TestBasicExpiryTimeSpan(bool disablePTimes)
conn
.
KeyExpire
(
key
,
TimeSpan
.
MaxValue
,
CommandFlags
.
FireAndForget
);
var
e
=
conn
.
KeyTimeToLiveAsync
(
key
);
Assert
.
Null
(
muxer
.
Wait
(
a
)
);
var
time
=
muxer
.
Wait
(
b
)
;
Assert
.
Null
(
await
a
);
var
time
=
await
b
;
Assert
.
NotNull
(
time
);
Assert
.
True
(
time
>
TimeSpan
.
FromMinutes
(
59.9
)
&&
time
<=
TimeSpan
.
FromMinutes
(
60
));
Assert
.
Null
(
muxer
.
Wait
(
c
)
);
time
=
muxer
.
Wait
(
d
)
;
Assert
.
Null
(
await
c
);
time
=
await
d
;
Assert
.
NotNull
(
time
);
Assert
.
True
(
time
>
TimeSpan
.
FromMinutes
(
89.9
)
&&
time
<=
TimeSpan
.
FromMinutes
(
90
));
Assert
.
Null
(
muxer
.
Wait
(
e
)
);
Assert
.
Null
(
await
e
);
}
}
...
...
@@ -49,7 +50,7 @@ public void TestBasicExpiryTimeSpan(bool disablePTimes)
[
InlineData
(
false
,
true
)]
[
InlineData
(
true
,
false
)]
[
InlineData
(
false
,
false
)]
public
void
TestBasicExpiryDateTime
(
bool
disablePTimes
,
bool
utc
)
public
async
Task
TestBasicExpiryDateTime
(
bool
disablePTimes
,
bool
utc
)
{
using
(
var
muxer
=
Create
(
disabledCommands
:
GetMap
(
disablePTimes
)))
{
...
...
@@ -70,18 +71,18 @@ public void TestBasicExpiryDateTime(bool disablePTimes, bool utc)
conn
.
KeyExpire
(
key
,
DateTime
.
MaxValue
,
CommandFlags
.
FireAndForget
);
var
e
=
conn
.
KeyTimeToLiveAsync
(
key
);
Assert
.
Null
(
muxer
.
Wait
(
a
)
);
var
time
=
muxer
.
Wait
(
b
)
;
Assert
.
Null
(
await
a
);
var
time
=
await
b
;
Assert
.
NotNull
(
time
);
Log
(
"Time: {0}, Expected: {1}-{2}"
,
time
,
TimeSpan
.
FromMinutes
(
59
),
TimeSpan
.
FromMinutes
(
60
));
Assert
.
True
(
time
>=
TimeSpan
.
FromMinutes
(
59
));
Assert
.
True
(
time
<=
TimeSpan
.
FromMinutes
(
60
));
Assert
.
Null
(
muxer
.
Wait
(
c
)
);
time
=
muxer
.
Wait
(
d
)
;
Assert
.
Null
(
await
c
);
time
=
await
d
;
Assert
.
NotNull
(
time
);
Assert
.
True
(
time
>=
TimeSpan
.
FromMinutes
(
89
));
Assert
.
True
(
time
<=
TimeSpan
.
FromMinutes
(
90
));
Assert
.
Null
(
muxer
.
Wait
(
e
)
);
Assert
.
Null
(
await
e
);
}
}
}
...
...
StackExchange.Redis.Tests/Failover.cs
View file @
9e878625
...
...
@@ -236,8 +236,10 @@ public async Task SubscriptionsSurviveMasterSwitchAsync()
Log
(
"B: "
+
EndPointCollection
.
ToString
(
epB
));
subA
.
Publish
(
channel
,
"A1"
);
subB
.
Publish
(
channel
,
"B1"
);
subA
.
Ping
();
subB
.
Ping
();
Log
(
"SubA ping: "
+
subA
.
Ping
());
Log
(
"SubB ping: "
+
subB
.
Ping
());
// If redis is under load due to this suite, it may take a moment to send across.
await
Task
.
Delay
(
250
).
ForAwait
();
Assert
.
Equal
(
2
,
Interlocked
.
Read
(
ref
aCount
));
Assert
.
Equal
(
2
,
Interlocked
.
Read
(
ref
bCount
));
...
...
StackExchange.Redis.Tests/FloatingPoint.cs
View file @
9e878625
...
...
@@ -150,12 +150,12 @@ public async Task HashIncrDecrFloatingPointAsync()
double
sum
=
0
;
foreach
(
var
value
in
incr
)
{
await
db
.
HashIncrementAsync
(
key
,
field
,
value
).
ForAwait
(
);
var
t
=
db
.
HashIncrementAsync
(
key
,
field
,
value
);
sum
+=
value
;
}
foreach
(
var
value
in
decr
)
{
await
db
.
HashDecrementAsync
(
key
,
field
,
value
).
ForAwait
(
);
var
t
=
db
.
HashDecrementAsync
(
key
,
field
,
value
);
sum
-=
value
;
}
var
val
=
(
double
)
await
db
.
HashGetAsync
(
key
,
field
).
ForAwait
();
...
...
StackExchange.Redis.Tests/GeoTests.cs
View file @
9e878625
...
...
@@ -23,7 +23,7 @@ public void GeoAdd()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
// add while not there
Assert
.
True
(
db
.
GeoAdd
(
key
,
cefal
ù
.
Longitude
,
cefal
ù
.
Latitude
,
cefal
ù
.
Member
));
...
...
@@ -51,8 +51,8 @@ public void GetDistance()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
GeoAdd
(
key
,
all
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
GeoAdd
(
key
,
all
,
CommandFlags
.
FireAndForget
);
var
val
=
db
.
GeoDistance
(
key
,
"Palermo"
,
"Catania"
,
GeoUnit
.
Meters
);
Assert
.
True
(
val
.
HasValue
);
var
rounded
=
Math
.
Round
(
val
.
Value
,
10
);
...
...
@@ -71,8 +71,8 @@ public void GeoHash()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
GeoAdd
(
key
,
all
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
GeoAdd
(
key
,
all
,
CommandFlags
.
FireAndForget
);
var
hashes
=
db
.
GeoHash
(
key
,
new
RedisValue
[]
{
palermo
.
Member
,
"Nowhere"
,
agrigento
.
Member
});
Assert
.
Equal
(
3
,
hashes
.
Length
);
...
...
@@ -96,8 +96,8 @@ public void GeoGetPosition()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
GeoAdd
(
key
,
all
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
GeoAdd
(
key
,
all
,
CommandFlags
.
FireAndForget
);
var
pos
=
db
.
GeoPosition
(
key
,
palermo
.
Member
);
Assert
.
True
(
pos
.
HasValue
);
...
...
@@ -117,8 +117,8 @@ public void GeoRemove()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
GeoAdd
(
key
,
all
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
GeoAdd
(
key
,
all
,
CommandFlags
.
FireAndForget
);
var
pos
=
db
.
GeoPosition
(
key
,
"Palermo"
);
Assert
.
True
(
pos
.
HasValue
);
...
...
@@ -140,8 +140,8 @@ public void GeoRadius()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
GeoAdd
(
key
,
all
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
GeoAdd
(
key
,
all
,
CommandFlags
.
FireAndForget
);
var
results
=
db
.
GeoRadius
(
key
,
cefal
ù
.
Member
,
60
,
GeoUnit
.
Miles
,
2
,
Order
.
Ascending
);
Assert
.
Equal
(
2
,
results
.
Length
);
...
...
@@ -180,7 +180,7 @@ public void GeoRadiusOverloads()
Skip
.
IfMissingFeature
(
conn
,
nameof
(
RedisFeatures
.
Geo
),
r
=>
r
.
Geo
);
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
Assert
.
True
(
db
.
GeoAdd
(
key
,
-
1.759925
,
52.19493
,
"steve"
));
Assert
.
True
(
db
.
GeoAdd
(
key
,
-
3.360655
,
54.66395
,
"dave"
));
...
...
StackExchange.Redis.Tests/Hashes.cs
View file @
9e878625
This diff is collapsed.
Click to expand it.
StackExchange.Redis.Tests/Helpers/redis-sharp.cs
View file @
9e878625
...
...
@@ -242,11 +242,11 @@ private bool SendDataCommand(byte[] data, string cmd, params object[] args)
if
(
socket
==
null
)
return
false
;
var
s
=
args
.
Length
>
0
?
S
tring
.
Format
(
cmd
,
args
)
:
cmd
;
var
s
=
args
.
Length
>
0
?
s
tring
.
Format
(
cmd
,
args
)
:
cmd
;
byte
[]
r
=
Encoding
.
UTF8
.
GetBytes
(
s
);
try
{
Log
(
"S: "
+
S
tring
.
Format
(
cmd
,
args
));
Log
(
"S: "
+
s
tring
.
Format
(
cmd
,
args
));
socket
.
Send
(
r
);
if
(
data
!=
null
)
{
...
...
@@ -272,11 +272,11 @@ private bool SendCommand(string cmd, params object[] args)
if
(
socket
==
null
)
return
false
;
var
s
=
args
?.
Length
>
0
?
S
tring
.
Format
(
cmd
,
args
)
:
cmd
;
var
s
=
args
?.
Length
>
0
?
s
tring
.
Format
(
cmd
,
args
)
:
cmd
;
byte
[]
r
=
Encoding
.
UTF8
.
GetBytes
(
s
);
try
{
Log
(
"S: "
+
S
tring
.
Format
(
cmd
,
args
));
Log
(
"S: "
+
s
tring
.
Format
(
cmd
,
args
));
socket
.
Send
(
r
);
}
catch
(
SocketException
)
...
...
@@ -293,7 +293,7 @@ private bool SendCommand(string cmd, params object[] args)
[
Conditional
(
"DEBUG"
)]
private
void
Log
(
string
fmt
,
params
object
[]
args
)
{
Console
.
WriteLine
(
"{0}"
,
S
tring
.
Format
(
fmt
,
args
).
Trim
());
Console
.
WriteLine
(
"{0}"
,
s
tring
.
Format
(
fmt
,
args
).
Trim
());
}
private
void
ExpectSuccess
()
...
...
@@ -416,7 +416,7 @@ private byte[] ReadData()
if
(
r
==
"$-1"
)
return
null
;
if
(
Int32
.
TryParse
(
r
.
Substring
(
1
),
out
int
n
))
if
(
int
.
TryParse
(
r
.
Substring
(
1
),
out
int
n
))
{
var
retbuf
=
new
byte
[
n
];
...
...
@@ -439,7 +439,7 @@ private byte[] ReadData()
//returns the number of matches
if
(
c
==
'*'
)
{
if
(
Int32
.
TryParse
(
r
.
Substring
(
1
),
out
int
n
))
if
(
int
.
TryParse
(
r
.
Substring
(
1
),
out
int
n
))
return
n
<=
0
?
new
byte
[
0
]
:
ReadData
();
throw
new
ResponseException
(
"Unexpected length parameter"
+
r
);
...
...
@@ -759,16 +759,16 @@ public byte[][] GetUnionOfSets(params string[] keys)
private
void
StoreSetCommands
(
string
cmd
,
string
destKey
,
params
string
[]
keys
)
{
if
(
S
tring
.
IsNullOrEmpty
(
cmd
))
if
(
s
tring
.
IsNullOrEmpty
(
cmd
))
throw
new
ArgumentNullException
(
nameof
(
cmd
));
if
(
S
tring
.
IsNullOrEmpty
(
destKey
))
if
(
s
tring
.
IsNullOrEmpty
(
destKey
))
throw
new
ArgumentNullException
(
nameof
(
destKey
));
if
(
keys
==
null
)
throw
new
ArgumentNullException
(
nameof
(
keys
));
SendExpectSuccess
(
"{0} {1} {2}\r\n"
,
cmd
,
destKey
,
S
tring
.
Join
(
" "
,
keys
));
SendExpectSuccess
(
"{0} {1} {2}\r\n"
,
cmd
,
destKey
,
s
tring
.
Join
(
" "
,
keys
));
}
public
void
StoreUnionOfSets
(
string
destKey
,
params
string
[]
keys
)
...
...
@@ -835,15 +835,15 @@ public class SortOptions
public
string
Key
{
get
;
set
;
}
public
bool
Descending
{
get
;
set
;
}
public
bool
Lexographically
{
get
;
set
;
}
public
Int32
LowerLimit
{
get
;
set
;
}
public
Int32
UpperLimit
{
get
;
set
;
}
public
int
LowerLimit
{
get
;
set
;
}
public
int
UpperLimit
{
get
;
set
;
}
public
string
By
{
get
;
set
;
}
public
string
StoreInKey
{
get
;
set
;
}
public
string
Get
{
get
;
set
;
}
public
string
ToCommand
()
{
var
command
=
"SORT "
+
this
.
Key
;
var
command
=
"SORT "
+
Key
;
if
(
LowerLimit
!=
0
||
UpperLimit
!=
0
)
command
+=
" LIMIT "
+
LowerLimit
+
" "
+
UpperLimit
;
if
(
Lexographically
)
...
...
@@ -857,4 +857,4 @@ public string ToCommand()
return
command
;
}
}
}
\ No newline at end of file
}
StackExchange.Redis.Tests/Issues/SO10504853.cs
View file @
9e878625
...
...
@@ -12,11 +12,12 @@ public class SO10504853 : TestBase
[
Fact
]
public
void
LoopLotsOfTrivialStuff
()
{
var
key
=
Me
();
Trace
.
WriteLine
(
"### init"
);
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
conn
.
KeyDelete
(
"lots-trivial"
);
conn
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
}
const
int
COUNT
=
2
;
for
(
int
i
=
0
;
i
<
COUNT
;
i
++)
...
...
@@ -25,14 +26,14 @@ public void LoopLotsOfTrivialStuff()
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
Assert
.
Equal
(
i
+
1
,
conn
.
StringIncrement
(
"lots-trivial"
));
Assert
.
Equal
(
i
+
1
,
conn
.
StringIncrement
(
key
));
}
}
Trace
.
WriteLine
(
"### close"
);
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
Assert
.
Equal
(
COUNT
,
(
long
)
conn
.
StringGet
(
"lots-trivial"
));
Assert
.
Equal
(
COUNT
,
(
long
)
conn
.
StringGet
(
key
));
}
}
...
...
@@ -42,12 +43,13 @@ public void ExecuteWithEmptyStartingPoint()
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
var
key
=
Me
();
var
task
=
new
{
priority
=
3
};
conn
.
KeyDeleteAsync
(
"item:1"
);
conn
.
HashSetAsync
(
"item:1"
,
"something else"
,
"abc"
);
conn
.
HashSetAsync
(
"item:1"
,
"priority"
,
task
.
priority
.
ToString
());
conn
.
KeyDeleteAsync
(
key
);
conn
.
HashSetAsync
(
key
,
"something else"
,
"abc"
);
conn
.
HashSetAsync
(
key
,
"priority"
,
task
.
priority
.
ToString
());
var
taskResult
=
conn
.
HashGetAsync
(
"item:1"
,
"priority"
);
var
taskResult
=
conn
.
HashGetAsync
(
key
,
"priority"
);
conn
.
Wait
(
taskResult
);
...
...
@@ -60,17 +62,18 @@ public void ExecuteWithEmptyStartingPoint()
[
Fact
]
public
void
ExecuteWithNonHashStartingPoint
()
{
var
key
=
Me
();
Assert
.
Throws
<
RedisServerException
>(()
=>
{
using
(
var
muxer
=
Create
())
{
var
conn
=
muxer
.
GetDatabase
();
var
task
=
new
{
priority
=
3
};
conn
.
KeyDeleteAsync
(
"item:1"
);
conn
.
StringSetAsync
(
"item:1"
,
"not a hash"
);
conn
.
HashSetAsync
(
"item:1"
,
"priority"
,
task
.
priority
.
ToString
());
conn
.
KeyDeleteAsync
(
key
);
conn
.
StringSetAsync
(
key
,
"not a hash"
);
conn
.
HashSetAsync
(
key
,
"priority"
,
task
.
priority
.
ToString
());
var
taskResult
=
conn
.
HashGetAsync
(
"item:1"
,
"priority"
);
var
taskResult
=
conn
.
HashGetAsync
(
key
,
"priority"
);
try
{
...
...
StackExchange.Redis.Tests/Issues/SO10825542.cs
View file @
9e878625
using
System
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Xunit
;
using
Xunit.Abstractions
;
...
...
@@ -10,7 +11,7 @@ public class SO10825542 : TestBase
public
SO10825542
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
[
Fact
]
public
void
Execute
()
public
async
Task
Execute
()
{
using
(
var
muxer
=
Create
())
{
...
...
@@ -18,14 +19,13 @@ public void Execute()
var
con
=
muxer
.
GetDatabase
();
// set the field value and expiration
con
.
HashSetAsync
(
key
,
"field1"
,
Encoding
.
UTF8
.
GetBytes
(
"hello world"
));
con
.
KeyExpireAsync
(
key
,
TimeSpan
.
FromSeconds
(
7200
));
con
.
HashSetAsync
(
key
,
"field2"
,
"fooobar"
);
var
task
=
con
.
HashGetAllAsync
(
key
);
con
.
Wait
(
task
);
var
hsa
=
con
.
HashSetAsync
(
key
,
"field1"
,
Encoding
.
UTF8
.
GetBytes
(
"hello world"
));
var
kea
=
con
.
KeyExpireAsync
(
key
,
TimeSpan
.
FromSeconds
(
7200
));
var
hsa2
=
con
.
HashSetAsync
(
key
,
"field2"
,
"fooobar"
);
var
result
=
await
con
.
HashGetAllAsync
(
key
).
ForAwait
();
Assert
.
Equal
(
2
,
task
.
R
esult
.
Length
);
var
dict
=
task
.
R
esult
.
ToStringDictionary
();
Assert
.
Equal
(
2
,
r
esult
.
Length
);
var
dict
=
r
esult
.
ToStringDictionary
();
Assert
.
Equal
(
"hello world"
,
dict
[
"field1"
]);
Assert
.
Equal
(
"fooobar"
,
dict
[
"field2"
]);
}
...
...
StackExchange.Redis.Tests/Issues/SO24807536.cs
View file @
9e878625
...
...
@@ -19,9 +19,9 @@ public async Task Exec()
var
cache
=
conn
.
GetDatabase
();
// setup some data
cache
.
KeyDelete
(
key
);
cache
.
HashSet
(
key
,
"full"
,
"some value"
);
cache
.
KeyExpire
(
key
,
TimeSpan
.
FromSeconds
(
3
));
cache
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
cache
.
HashSet
(
key
,
"full"
,
"some value"
,
flags
:
CommandFlags
.
FireAndForget
);
cache
.
KeyExpire
(
key
,
TimeSpan
.
FromSeconds
(
3
)
,
CommandFlags
.
FireAndForget
);
// test while exists
var
keyExists
=
cache
.
KeyExists
(
key
);
...
...
@@ -41,7 +41,7 @@ public async Task Exec()
Assert
.
False
(
keyExists
);
Assert
.
Null
(
ttl
);
var
r
=
fullWait
.
Resul
t
;
var
r
=
await
fullWai
t
;
Assert
.
True
(
r
.
IsNull
);
Assert
.
Null
((
string
)
r
);
}
...
...
StackExchange.Redis.Tests/Issues/SO25113323.cs
View file @
9e878625
using
System
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Xunit
;
using
Xunit.Abstractions
;
...
...
@@ -18,7 +17,7 @@ public async Task SetExpirationToPassed()
{
// Given
var
cache
=
conn
.
GetDatabase
();
cache
.
KeyDelete
(
key
);
cache
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
cache
.
HashSet
(
key
,
"full"
,
"test"
,
When
.
NotExists
,
CommandFlags
.
PreferMaster
);
await
Task
.
Delay
(
2000
).
ForAwait
();
...
...
StackExchange.Redis.Tests/Keys.cs
View file @
9e878625
...
...
@@ -38,7 +38,7 @@ public void FlushFetchRandomKey()
Skip
.
IfMissingDatabase
(
conn
,
dbId
);
var
db
=
conn
.
GetDatabase
(
dbId
);
var
prefix
=
Me
();
conn
.
GetServer
(
TestConfig
.
Current
.
MasterServerAndPort
).
FlushDatabase
(
dbId
);
conn
.
GetServer
(
TestConfig
.
Current
.
MasterServerAndPort
).
FlushDatabase
(
dbId
,
CommandFlags
.
FireAndForget
);
string
anyKey
=
db
.
KeyRandom
();
Assert
.
Null
(
anyKey
);
...
...
@@ -56,12 +56,12 @@ public void Zeros()
{
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
StringSet
(
key
,
123
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
StringSet
(
key
,
123
,
flags
:
CommandFlags
.
FireAndForget
);
int
k
=
(
int
)
db
.
StringGet
(
key
);
Assert
.
Equal
(
123
,
k
);
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
int
i
=
(
int
)
db
.
StringGet
(
key
);
Assert
.
Equal
(
0
,
i
);
...
...
StackExchange.Redis.Tests/Lex.cs
View file @
9e878625
...
...
@@ -14,7 +14,7 @@ public void QueryRangeAndLengthByLex()
{
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
SortedSetEntry
[]
...
...
@@ -26,7 +26,7 @@ public void QueryRangeAndLengthByLex()
new
SortedSetEntry
(
"e"
,
0
),
new
SortedSetEntry
(
"f"
,
0
),
new
SortedSetEntry
(
"g"
,
0
),
});
}
,
CommandFlags
.
FireAndForget
);
var
set
=
db
.
SortedSetRangeByValue
(
key
,
default
(
RedisValue
),
"c"
);
var
count
=
db
.
SortedSetLengthByValue
(
key
,
default
(
RedisValue
),
"c"
);
...
...
@@ -43,7 +43,6 @@ public void QueryRangeAndLengthByLex()
set
=
db
.
SortedSetRangeByValue
(
key
,
"aaa"
,
"g"
,
Exclude
.
Stop
,
1
,
3
);
Equate
(
set
,
set
.
Length
,
"c"
,
"d"
,
"e"
);
set
=
db
.
SortedSetRangeByValue
(
key
,
"aaa"
,
"g"
,
Exclude
.
Stop
,
Order
.
Descending
,
1
,
3
);
Equate
(
set
,
set
.
Length
,
"e"
,
"d"
,
"c"
);
...
...
@@ -59,7 +58,7 @@ public void RemoveRangeByLex()
{
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
SortedSetEntry
[]
...
...
@@ -69,7 +68,7 @@ public void RemoveRangeByLex()
new
SortedSetEntry
(
"c"
,
0
),
new
SortedSetEntry
(
"d"
,
0
),
new
SortedSetEntry
(
"e"
,
0
),
});
}
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
SortedSetEntry
[]
{
...
...
@@ -78,7 +77,7 @@ public void RemoveRangeByLex()
new
SortedSetEntry
(
"zip"
,
0
),
new
SortedSetEntry
(
"ALPHA"
,
0
),
new
SortedSetEntry
(
"alpha"
,
0
),
});
}
,
CommandFlags
.
FireAndForget
);
var
set
=
db
.
SortedSetRangeByRank
(
key
);
Equate
(
set
,
set
.
Length
,
"ALPHA"
,
"aaaa"
,
"alpha"
,
"b"
,
"c"
,
"d"
,
"e"
,
"foo"
,
"zap"
,
"zip"
);
...
...
StackExchange.Redis.Tests/Lists.cs
View file @
9e878625
...
...
@@ -17,18 +17,18 @@ public void Ranges()
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
ListRightPush
(
key
,
"abcdefghijklmnopqrstuvwxyz"
.
Select
(
x
=>
(
RedisValue
)
x
.
ToString
()).
ToArray
());
db
.
ListRightPush
(
key
,
"abcdefghijklmnopqrstuvwxyz"
.
Select
(
x
=>
(
RedisValue
)
x
.
ToString
()).
ToArray
()
,
CommandFlags
.
FireAndForget
);
Assert
.
Equal
(
26
,
db
.
ListLength
(
key
));
Assert
.
Equal
(
"abcdefghijklmnopqrstuvwxyz"
,
string
.
Concat
(
db
.
ListRange
(
key
)));
var
last10
=
db
.
ListRange
(
key
,
-
10
,
-
1
);
Assert
.
Equal
(
"qrstuvwxyz"
,
string
.
Concat
(
last10
));
db
.
ListTrim
(
key
,
0
,
-
11
);
db
.
ListTrim
(
key
,
0
,
-
11
,
CommandFlags
.
FireAndForget
);
Assert
.
Equal
(
16
,
db
.
ListLength
(
key
));
Assert
.
Equal
(
"abcdefghijklmnop"
,
string
.
Concat
(
db
.
ListRange
(
key
)));
}
}
}
}
\ No newline at end of file
}
StackExchange.Redis.Tests/Locking.cs
View file @
9e878625
...
...
@@ -72,35 +72,8 @@ public void TestOpCountByVersionLocal_UpLevel()
{
TestLockOpCountByVersion
(
conn
,
1
,
false
);
TestLockOpCountByVersion
(
conn
,
1
,
true
);
//TestManualLockOpCountByVersion(conn, 5, false);
//TestManualLockOpCountByVersion(conn, 3, true);
}
}
//[Test]
//public void TestOpCountByVersionLocal_DownLevel()
//{
// using (var conn = GetUnsecuredConnection(open: false))
// {
// conn.SetServerVersion(new Version(2, 6, 0), ServerType.Master);
// TestLockOpCountByVersion(conn, 5, false);
// TestLockOpCountByVersion(conn, 3, true);
// //TestManualLockOpCountByVersion(conn, 5, false);
// //TestManualLockOpCountByVersion(conn, 3, true);
// }
//}
//[Test]
//public void TestOpCountByVersionRemote()
//{
// using (var conn = GetRemoteConnection(open: false))
// {
// TestLockOpCountByVersion(conn, 1, false);
// TestLockOpCountByVersion(conn, 1, true);
// //TestManualLockOpCountByVersion(conn, 1, false);
// //TestManualLockOpCountByVersion(conn, 1, true);
// }
//}
private
void
TestLockOpCountByVersion
(
ConnectionMultiplexer
conn
,
int
expectedOps
,
bool
existFirst
)
{
...
...
@@ -108,13 +81,13 @@ private void TestLockOpCountByVersion(ConnectionMultiplexer conn, int expectedOp
RedisKey
Key
=
Me
();
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
Key
);
db
.
KeyDelete
(
Key
,
CommandFlags
.
FireAndForget
);
RedisValue
newVal
=
"us:"
+
Guid
.
NewGuid
().
ToString
();
RedisValue
expectedVal
=
newVal
;
if
(
existFirst
)
{
expectedVal
=
"other:"
+
Guid
.
NewGuid
().
ToString
();
db
.
StringSet
(
Key
,
expectedVal
,
TimeSpan
.
FromSeconds
(
LockDuration
));
db
.
StringSet
(
Key
,
expectedVal
,
TimeSpan
.
FromSeconds
(
LockDuration
)
,
flags
:
CommandFlags
.
FireAndForget
);
}
long
countBefore
=
GetServer
(
conn
).
GetCounters
().
Interactive
.
OperationCount
;
...
...
@@ -145,7 +118,7 @@ private ConnectionMultiplexer Create(TestMode mode)
}
[
Theory
,
MemberData
(
nameof
(
TestModes
))]
public
void
TakeLockAndExtend
(
TestMode
mode
)
public
async
Task
TakeLockAndExtend
(
TestMode
mode
)
{
bool
withTran
=
mode
==
TestMode
.
MultiExec
;
using
(
var
conn
=
Create
(
mode
))
...
...
@@ -158,7 +131,7 @@ public void TakeLockAndExtend(TestMode mode)
var
db
=
conn
.
GetDatabase
(
DB
);
db
.
KeyDelete
(
Key
);
db
.
KeyDelete
(
Key
,
CommandFlags
.
FireAndForget
);
var
t1
=
db
.
LockTakeAsync
(
Key
,
right
,
TimeSpan
.
FromSeconds
(
20
));
var
t1b
=
db
.
LockTakeAsync
(
Key
,
wrong
,
TimeSpan
.
FromSeconds
(
10
));
...
...
@@ -178,22 +151,22 @@ public void TakeLockAndExtend(TestMode mode)
Assert
.
NotEqual
(
default
(
RedisValue
),
right
);
Assert
.
NotEqual
(
default
(
RedisValue
),
wrong
);
Assert
.
NotEqual
(
right
,
wrong
);
Assert
.
True
(
conn
.
Wait
(
t1
)
,
"1"
);
Assert
.
False
(
conn
.
Wait
(
t1b
)
,
"1b"
);
Assert
.
Equal
(
right
,
conn
.
Wait
(
t2
)
);
if
(
withTran
)
Assert
.
False
(
conn
.
Wait
(
t3
)
,
"3"
);
Assert
.
Equal
(
right
,
conn
.
Wait
(
t4
)
);
if
(
withTran
)
Assert
.
False
(
conn
.
Wait
(
t5
)
,
"5"
);
Assert
.
Equal
(
right
,
conn
.
Wait
(
t6
)
);
var
ttl
=
conn
.
Wait
(
t7
).
Value
.
TotalSeconds
;
Assert
.
True
(
await
t1
,
"1"
);
Assert
.
False
(
await
t1b
,
"1b"
);
Assert
.
Equal
(
right
,
await
t2
);
if
(
withTran
)
Assert
.
False
(
await
t3
,
"3"
);
Assert
.
Equal
(
right
,
await
t4
);
if
(
withTran
)
Assert
.
False
(
await
t5
,
"5"
);
Assert
.
Equal
(
right
,
await
t6
);
var
ttl
=
(
await
t7
).
Value
.
TotalSeconds
;
Assert
.
True
(
ttl
>
0
&&
ttl
<=
20
,
"7"
);
Assert
.
True
(
conn
.
Wait
(
t8
)
,
"8"
);
Assert
.
Equal
(
right
,
conn
.
Wait
(
t9
)
);
ttl
=
conn
.
Wait
(
t10
).
Value
.
TotalSeconds
;
Assert
.
True
(
await
t8
,
"8"
);
Assert
.
Equal
(
right
,
await
t9
);
ttl
=
(
await
t10
).
Value
.
TotalSeconds
;
Assert
.
True
(
ttl
>
50
&&
ttl
<=
60
,
"10"
);
Assert
.
True
(
conn
.
Wait
(
t11
)
,
"11"
);
Assert
.
Null
((
string
)
conn
.
Wait
(
t12
)
);
Assert
.
True
(
conn
.
Wait
(
t13
)
,
"13"
);
Assert
.
True
(
await
t11
,
"11"
);
Assert
.
Null
((
string
)
await
t12
);
Assert
.
True
(
await
t13
,
"13"
);
}
}
...
...
@@ -226,7 +199,7 @@ public void TakeLockAndExtend(TestMode mode)
//}
[
Theory
,
MemberData
(
nameof
(
TestModes
))]
public
void
TestBasicLockNotTaken
(
TestMode
testMode
)
public
async
Task
TestBasicLockNotTaken
(
TestMode
testMode
)
{
using
(
var
conn
=
Create
(
testMode
))
{
...
...
@@ -241,14 +214,14 @@ public void TestBasicLockNotTaken(TestMode testMode)
var
key
=
Me
();
for
(
int
i
=
0
;
i
<
LOOP
;
i
++)
{
db
.
KeyDeleteAsync
(
key
);
var
d
=
db
.
KeyDeleteAsync
(
key
);
taken
=
db
.
LockTakeAsync
(
key
,
"new-value"
,
TimeSpan
.
FromSeconds
(
10
));
newValue
=
db
.
StringGetAsync
(
key
);
ttl
=
db
.
KeyTimeToLiveAsync
(
key
);
}
Assert
.
True
(
conn
.
Wait
(
taken
)
,
"taken"
);
Assert
.
Equal
(
"new-value"
,
(
string
)
conn
.
Wait
(
newValue
)
);
var
ttlValue
=
conn
.
Wait
(
ttl
).
Value
.
TotalSeconds
;
Assert
.
True
(
await
taken
,
"taken"
);
Assert
.
Equal
(
"new-value"
,
(
string
)
await
newValue
);
var
ttlValue
=
(
await
ttl
).
Value
.
TotalSeconds
;
Assert
.
True
(
ttlValue
>=
8
&&
ttlValue
<=
10
,
"ttl"
);
Assert
.
Equal
(
0
,
errorCount
);
...
...
@@ -256,21 +229,21 @@ public void TestBasicLockNotTaken(TestMode testMode)
}
[
Theory
,
MemberData
(
nameof
(
TestModes
))]
public
void
TestBasicLockTaken
(
TestMode
testMode
)
public
async
Task
TestBasicLockTaken
(
TestMode
testMode
)
{
using
(
var
conn
=
Create
(
testMode
))
{
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
StringSet
(
key
,
"old-value"
,
TimeSpan
.
FromSeconds
(
20
));
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
StringSet
(
key
,
"old-value"
,
TimeSpan
.
FromSeconds
(
20
)
,
flags
:
CommandFlags
.
FireAndForget
);
var
taken
=
db
.
LockTakeAsync
(
key
,
"new-value"
,
TimeSpan
.
FromSeconds
(
10
));
var
newValue
=
db
.
StringGetAsync
(
key
);
var
ttl
=
db
.
KeyTimeToLiveAsync
(
key
);
Assert
.
False
(
conn
.
Wait
(
taken
)
,
"taken"
);
Assert
.
Equal
(
"old-value"
,
(
string
)
conn
.
Wait
(
newValue
)
);
var
ttlValue
=
conn
.
Wait
(
ttl
).
Value
.
TotalSeconds
;
Assert
.
False
(
await
taken
,
"taken"
);
Assert
.
Equal
(
"old-value"
,
(
string
)
await
newValue
);
var
ttlValue
=
(
await
ttl
).
Value
.
TotalSeconds
;
Assert
.
True
(
ttlValue
>=
18
&&
ttlValue
<=
20
,
"ttl"
);
}
}
...
...
StackExchange.Redis.Tests/MassiveOps.cs
View file @
9e878625
...
...
@@ -22,10 +22,10 @@ public async Task MassiveBulkOpsAsync(bool withContinuation)
RedisKey
key
=
"MBOA"
;
var
conn
=
muxer
.
GetDatabase
();
await
conn
.
PingAsync
().
ForAwait
();
Action
<
Task
>
nonTrivial
=
delegate
void
nonTrivial
(
Task
_
)
{
Thread
.
SpinWait
(
5
);
}
;
}
var
watch
=
Stopwatch
.
StartNew
();
for
(
int
i
=
0
;
i
<=
AsyncOpsQty
;
i
++)
{
...
...
@@ -53,7 +53,7 @@ public void MassiveBulkOpsSync(int threads)
{
RedisKey
key
=
"MBOS"
;
var
conn
=
muxer
.
GetDatabase
();
conn
.
KeyDelete
(
key
);
conn
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
#if DEBUG
long
oldAlloc
=
ConnectionMultiplexer
.
GetResultBoxAllocationCount
();
#endif
...
...
@@ -61,7 +61,7 @@ public void MassiveBulkOpsSync(int threads)
{
for
(
int
i
=
0
;
i
<
workPerThread
;
i
++)
{
conn
.
StringIncrement
(
key
);
conn
.
StringIncrement
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
}
},
threads
);
...
...
StackExchange.Redis.Tests/Migrate.cs
View file @
9e878625
...
...
@@ -8,9 +8,10 @@ public class Migrate : TestBase
{
public
Migrate
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
[
Fact
]
public
void
Basic
()
{
var
fromConfig
=
new
ConfigurationOptions
{
EndPoints
=
{
{
TestConfig
.
Current
.
Master
Server
,
TestConfig
.
Current
.
SecurePort
}
},
Password
=
TestConfig
.
Current
.
SecurePassword
};
var
fromConfig
=
new
ConfigurationOptions
{
EndPoints
=
{
{
TestConfig
.
Current
.
Secure
Server
,
TestConfig
.
Current
.
SecurePort
}
},
Password
=
TestConfig
.
Current
.
SecurePassword
};
var
toConfig
=
new
ConfigurationOptions
{
EndPoints
=
{
{
TestConfig
.
Current
.
MasterServer
,
TestConfig
.
Current
.
MasterPort
}
}
};
using
(
var
from
=
ConnectionMultiplexer
.
Connect
(
fromConfig
))
using
(
var
to
=
ConnectionMultiplexer
.
Connect
(
toConfig
))
...
...
@@ -18,11 +19,11 @@ public void Basic()
RedisKey
key
=
Me
();
var
fromDb
=
from
.
GetDatabase
();
var
toDb
=
to
.
GetDatabase
();
fromDb
.
KeyDelete
(
key
);
toDb
.
KeyDelete
(
key
);
fromDb
.
StringSet
(
key
,
"foo"
);
fromDb
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
toDb
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
fromDb
.
StringSet
(
key
,
"foo"
,
flags
:
CommandFlags
.
FireAndForget
);
var
dest
=
to
.
GetEndPoints
(
true
).
Single
();
fromDb
.
KeyMigrate
(
key
,
dest
);
fromDb
.
KeyMigrate
(
key
,
dest
,
flags
:
CommandFlags
.
FireAndForget
);
Assert
.
False
(
fromDb
.
KeyExists
(
key
));
Assert
.
True
(
toDb
.
KeyExists
(
key
));
string
s
=
toDb
.
StringGet
(
key
);
...
...
StackExchange.Redis.Tests/MultiAdd.cs
View file @
9e878625
...
...
@@ -16,22 +16,22 @@ public void AddSortedSetEveryWay()
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
SortedSetAdd
(
key
,
"a"
,
1
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
"a"
,
1
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
[]
{
new
SortedSetEntry
(
"b"
,
2
)
});
new
SortedSetEntry
(
"b"
,
2
)
}
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
[]
{
new
SortedSetEntry
(
"c"
,
3
),
new
SortedSetEntry
(
"d"
,
4
)});
new
SortedSetEntry
(
"d"
,
4
)}
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
[]
{
new
SortedSetEntry
(
"e"
,
5
),
new
SortedSetEntry
(
"f"
,
6
),
new
SortedSetEntry
(
"g"
,
7
)});
new
SortedSetEntry
(
"g"
,
7
)}
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
new
[]
{
new
SortedSetEntry
(
"h"
,
8
),
new
SortedSetEntry
(
"i"
,
9
),
new
SortedSetEntry
(
"j"
,
10
),
new
SortedSetEntry
(
"k"
,
11
)});
new
SortedSetEntry
(
"k"
,
11
)}
,
CommandFlags
.
FireAndForget
);
var
vals
=
db
.
SortedSetRangeByScoreWithScores
(
key
);
string
s
=
string
.
Join
(
","
,
vals
.
OrderByDescending
(
x
=>
x
.
Score
).
Select
(
x
=>
x
.
Element
));
Assert
.
Equal
(
"k,j,i,h,g,f,e,d,c,b,a"
,
s
);
...
...
@@ -48,22 +48,22 @@ public void AddHashEveryWay()
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
HashSet
(
key
,
"a"
,
1
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
"a"
,
1
,
flags
:
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
new
[]
{
new
HashEntry
(
"b"
,
2
)
});
new
HashEntry
(
"b"
,
2
)
}
,
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
new
[]
{
new
HashEntry
(
"c"
,
3
),
new
HashEntry
(
"d"
,
4
)});
new
HashEntry
(
"d"
,
4
)}
,
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
new
[]
{
new
HashEntry
(
"e"
,
5
),
new
HashEntry
(
"f"
,
6
),
new
HashEntry
(
"g"
,
7
)});
new
HashEntry
(
"g"
,
7
)}
,
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
new
[]
{
new
HashEntry
(
"h"
,
8
),
new
HashEntry
(
"i"
,
9
),
new
HashEntry
(
"j"
,
10
),
new
HashEntry
(
"k"
,
11
)});
new
HashEntry
(
"k"
,
11
)}
,
CommandFlags
.
FireAndForget
);
var
vals
=
db
.
HashGetAll
(
key
);
string
s
=
string
.
Join
(
","
,
vals
.
OrderByDescending
(
x
=>
(
double
)
x
.
Value
).
Select
(
x
=>
x
.
Name
));
Assert
.
Equal
(
"k,j,i,h,g,f,e,d,c,b,a"
,
s
);
...
...
@@ -80,12 +80,12 @@ public void AddSetEveryWay()
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
SetAdd
(
key
,
"a"
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"b"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"c"
,
"d"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"e"
,
"f"
,
"g"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"h"
,
"i"
,
"j"
,
"k"
});
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"a"
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"b"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"c"
,
"d"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"e"
,
"f"
,
"g"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"h"
,
"i"
,
"j"
,
"k"
}
,
CommandFlags
.
FireAndForget
);
var
vals
=
db
.
SetMembers
(
key
);
string
s
=
string
.
Join
(
","
,
vals
.
OrderByDescending
(
x
=>
x
));
...
...
@@ -101,12 +101,12 @@ public void AddSetEveryWayNumbers()
var
db
=
conn
.
GetDatabase
();
RedisKey
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
SetAdd
(
key
,
"a"
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"1"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"11"
,
"2"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"10"
,
"3"
,
"1.5"
});
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"2.2"
,
"-1"
,
"s"
,
"t"
});
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"a"
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"1"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"11"
,
"2"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"10"
,
"3"
,
"1.5"
}
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
new
RedisValue
[]
{
"2.2"
,
"-1"
,
"s"
,
"t"
}
,
CommandFlags
.
FireAndForget
);
var
vals
=
db
.
SetMembers
(
key
);
string
s
=
string
.
Join
(
","
,
vals
.
OrderByDescending
(
x
=>
x
));
...
...
StackExchange.Redis.Tests/Performance.cs
View file @
9e878625
...
...
@@ -124,7 +124,7 @@ public async Task BasicStringGetPerf()
Assert
.
Equal
(
"some value"
,
asyncVal
);
// let's allow 20% async overhead
// But with a floor, since the base can often be zero
Assert
.
True
(
asyncTimer
.
ElapsedMilliseconds
<=
System
.
Math
.
Max
(
syncTimer
.
ElapsedMilliseconds
*
1.2
M
,
2
0
));
Assert
.
True
(
asyncTimer
.
ElapsedMilliseconds
<=
System
.
Math
.
Max
(
syncTimer
.
ElapsedMilliseconds
*
1.2
M
,
5
0
));
}
}
}
...
...
StackExchange.Redis.Tests/PreserveOrder.cs
View file @
9e878625
...
...
@@ -20,7 +20,7 @@ public void Execute()
var
received
=
new
List
<
int
>();
Log
(
"Subscribing..."
);
const
int
COUNT
=
1000
;
sub
.
Subscribe
(
"foo"
,
(
channel
,
message
)
=>
sub
.
Subscribe
(
"foo"
,
(
_
,
message
)
=>
{
lock
(
received
)
{
...
...
StackExchange.Redis.Tests/Profiling.cs
View file @
9e878625
...
...
@@ -32,28 +32,32 @@ public void Simple()
var
dbId
=
TestConfig
.
GetDedicatedDB
();
var
db
=
conn
.
GetDatabase
(
dbId
);
db
.
StringSet
(
key
,
"world"
);
var
val
=
db
.
StringGet
(
key
);
Assert
.
Equal
(
"world"
,
(
string
)
val
);
var
result
=
db
.
ScriptEvaluate
(
LuaScript
.
Prepare
(
"return redis.call('get', @key)"
),
new
{
key
=
(
RedisKey
)
key
});
Assert
.
Equal
(
"world"
,
result
.
AsString
());
var
val
=
db
.
StringGet
(
key
);
Assert
.
Equal
(
"world"
,
(
string
)
val
);
var
cmds
=
conn
.
FinishProfiling
(
profiler
.
MyContext
);
var
i
=
0
;
foreach
(
var
cmd
in
cmds
)
{
Log
(
"Command {0}
: {1}"
,
i
++
,
cmd
.
ToString
().
Replace
(
"\n"
,
", "
));
Log
(
"Command {0}
(DB: {1}): {2}"
,
i
++,
cmd
.
Db
,
cmd
.
ToString
().
Replace
(
"\n"
,
", "
));
}
Assert
.
Equal
(
3
,
cmds
.
Count
());
Log
(
"Checking for SET"
);
var
set
=
cmds
.
SingleOrDefault
(
cmd
=>
cmd
.
Command
==
"SET"
);
Assert
.
NotNull
(
set
);
Log
(
"Checking for GET"
);
var
get
=
cmds
.
SingleOrDefault
(
cmd
=>
cmd
.
Command
==
"GET"
);
Assert
.
NotNull
(
get
);
Log
(
"Checking for EVAL"
);
var
eval
=
cmds
.
SingleOrDefault
(
cmd
=>
cmd
.
Command
==
"EVAL"
);
Assert
.
NotNull
(
eval
);
Assert
.
True
(
set
.
CommandCreated
<=
get
.
CommandCreated
);
Assert
.
True
(
get
.
CommandCreated
<=
eval
.
CommandCreated
);
Assert
.
Equal
(
3
,
cmds
.
Count
());
Assert
.
True
(
set
.
CommandCreated
<=
eval
.
CommandCreated
);
Assert
.
True
(
eval
.
CommandCreated
<=
get
.
CommandCreated
);
AssertProfiledCommandValues
(
set
,
conn
,
dbId
);
...
...
@@ -67,14 +71,14 @@ private static void AssertProfiledCommandValues(IProfiledCommand command, Connec
{
Assert
.
Equal
(
dbId
,
command
.
Db
);
Assert
.
Equal
(
conn
.
GetEndPoints
()[
0
],
command
.
EndPoint
);
Assert
.
True
(
command
.
CreationToEnqueued
>
TimeSpan
.
Zero
);
Assert
.
True
(
command
.
EnqueuedToSending
>
TimeSpan
.
Zero
);
Assert
.
True
(
command
.
SentToResponse
>
TimeSpan
.
Zero
);
Assert
.
True
(
command
.
ResponseToCompletion
>
TimeSpan
.
Zero
);
Assert
.
True
(
command
.
ElapsedTime
>
TimeSpan
.
Zero
);
Assert
.
True
(
command
.
ElapsedTime
>
command
.
CreationToEnqueued
&&
command
.
ElapsedTime
>
command
.
EnqueuedToSending
&&
command
.
ElapsedTime
>
command
.
SentToResponse
);
Assert
.
True
(
command
.
RetransmissionOf
==
null
);
Assert
.
True
(
command
.
RetransmissionReason
==
null
);
Assert
.
True
(
command
.
CreationToEnqueued
>
TimeSpan
.
Zero
,
nameof
(
command
.
CreationToEnqueued
)
);
Assert
.
True
(
command
.
EnqueuedToSending
>
TimeSpan
.
Zero
,
nameof
(
command
.
EnqueuedToSending
)
);
Assert
.
True
(
command
.
SentToResponse
>
TimeSpan
.
Zero
,
nameof
(
command
.
SentToResponse
)
);
Assert
.
True
(
command
.
ResponseToCompletion
>
TimeSpan
.
Zero
,
nameof
(
command
.
ResponseToCompletion
)
);
Assert
.
True
(
command
.
ElapsedTime
>
TimeSpan
.
Zero
,
nameof
(
command
.
ElapsedTime
)
);
Assert
.
True
(
command
.
ElapsedTime
>
command
.
CreationToEnqueued
&&
command
.
ElapsedTime
>
command
.
EnqueuedToSending
&&
command
.
ElapsedTime
>
command
.
SentToResponse
,
"Comparisons"
);
Assert
.
True
(
command
.
RetransmissionOf
==
null
,
nameof
(
command
.
RetransmissionOf
)
);
Assert
.
True
(
command
.
RetransmissionReason
==
null
,
nameof
(
command
.
RetransmissionReason
)
);
}
[
Fact
]
...
...
@@ -89,8 +93,8 @@ public void ManyThreads()
conn
.
BeginProfiling
(
profiler
.
MyContext
);
var
threads
=
new
List
<
Thread
>();
for
(
var
i
=
0
;
i
<
16
;
i
++)
const
int
CountPer
=
100
;
for
(
var
i
=
1
;
i
<=
16
;
i
++)
{
var
db
=
conn
.
GetDatabase
(
i
);
...
...
@@ -98,7 +102,7 @@ public void ManyThreads()
{
var
threadTasks
=
new
List
<
Task
>();
for
(
var
j
=
0
;
j
<
1000
;
j
++)
for
(
var
j
=
0
;
j
<
CountPer
;
j
++)
{
var
task
=
db
.
StringSetAsync
(
prefix
+
j
,
""
+
j
);
threadTasks
.
Add
(
task
);
...
...
@@ -112,22 +116,27 @@ public void ManyThreads()
threads
.
ForEach
(
thread
=>
thread
.
Join
());
var
allVals
=
conn
.
FinishProfiling
(
profiler
.
MyContext
);
var
relevant
=
allVals
.
Where
(
cmd
=>
cmd
.
Db
>
0
).
ToList
();
var
kinds
=
allVals
.
Select
(
cmd
=>
cmd
.
Command
).
Distinct
().
ToList
();
var
kinds
=
relevant
.
Select
(
cmd
=>
cmd
.
Command
).
Distinct
().
ToList
();
foreach
(
var
k
in
kinds
)
{
Log
(
"Kind Seen: "
+
k
);
}
Assert
.
True
(
kinds
.
Count
<=
2
);
Assert
.
Contains
(
"SET"
,
kinds
);
if
(
kinds
.
Count
==
2
&&
!
kinds
.
Contains
(
"SELECT"
))
if
(
kinds
.
Count
==
2
&&
!
kinds
.
Contains
(
"SELECT"
)
&&
!
kinds
.
Contains
(
"GET"
)
)
{
Assert
.
True
(
false
,
"Non-SET, Non-SELECT command seen"
);
Assert
.
True
(
false
,
"Non-SET, Non-SELECT
, Non-GET
command seen"
);
}
Assert
.
Equal
(
16
*
1000
,
allVals
.
Count
()
);
Assert
.
Equal
(
16
*
CountPer
,
relevant
.
Count
);
Assert
.
Equal
(
16
,
allVals
.
Select
(
cmd
=>
cmd
.
Db
).
Distinct
().
Count
());
for
(
var
i
=
0
;
i
<
16
;
i
++)
for
(
var
i
=
1
;
i
<=
16
;
i
++)
{
var
setsInDb
=
allVals
.
Count
(
cmd
=>
cmd
.
Db
==
i
&&
cmd
.
Command
==
"SET"
);
Assert
.
Equal
(
1000
,
setsInDb
);
var
setsInDb
=
relevant
.
Count
(
cmd
=>
cmd
.
Db
==
i
);
Assert
.
Equal
(
CountPer
,
setsInDb
);
}
}
}
...
...
@@ -294,7 +303,7 @@ public async Task LeaksCollectedAndRePooled()
var
anyContext
=
LeaksCollectedAndRePooled_Initialize
(
conn
,
ThreadCount
);
// force collection of everything but `anyContext`
GC
.
Collect
(
3
,
GCCollectionMode
.
Forced
,
blocking
:
true
);
GC
.
Collect
(
3
,
GCCollectionMode
.
Forced
);
GC
.
WaitForPendingFinalizers
();
await
Task
.
Delay
(
TimeSpan
.
FromMinutes
(
1.01
)).
ForAwait
();
...
...
@@ -419,7 +428,7 @@ public void LowAllocationEnumerable()
conn
.
BeginProfiling
(
profiler
.
MyContext
);
var
prefix
=
Me
();
var
db
=
conn
.
GetDatabase
();
var
db
=
conn
.
GetDatabase
(
1
);
var
allTasks
=
new
List
<
Task
<
string
>>();
...
...
@@ -453,10 +462,10 @@ public void LowAllocationEnumerable()
Assert
.
True
(
object
.
ReferenceEquals
(
i
,
j
));
}
Assert
.
Equal
(
OuterLoop
,
res
.
Count
(
r
=>
r
.
Command
==
"GET"
));
Assert
.
Equal
(
OuterLoop
,
res
.
Count
(
r
=>
r
.
Command
==
"SET"
));
Assert
.
Equal
(
OuterLoop
*
2
,
res
.
Count
());
Assert
.
Equal
(
OuterLoop
,
res
.
Count
(
r
=>
r
.
Command
==
"GET"
&&
r
.
Db
>
0
));
Assert
.
Equal
(
OuterLoop
,
res
.
Count
(
r
=>
r
.
Command
==
"SET"
&&
r
.
Db
>
0
));
Assert
.
Equal
(
OuterLoop
*
2
,
res
.
Count
(
r
=>
r
.
Db
>
0
));
}
}
...
...
StackExchange.Redis.Tests/PubSub.cs
View file @
9e878625
...
...
@@ -270,9 +270,6 @@ private void TestMassivePublish(ISubscriber conn, string channel, string caption
{
const
int
loop
=
10000
;
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
);
GC
.
WaitForPendingFinalizers
();
var
tasks
=
new
Task
[
loop
];
var
withFAF
=
Stopwatch
.
StartNew
();
...
...
@@ -282,9 +279,6 @@ private void TestMassivePublish(ISubscriber conn, string channel, string caption
}
withFAF
.
Stop
();
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
);
GC
.
WaitForPendingFinalizers
();
var
withAsync
=
Stopwatch
.
StartNew
();
for
(
int
i
=
0
;
i
<
loop
;
i
++)
{
...
...
@@ -530,7 +524,7 @@ public async Task PubSubGetAllCorrectOrder_OnMessage_Async()
}
[
Fact
]
public
void
TestPublishWithSubscribers
()
public
async
Task
TestPublishWithSubscribers
()
{
var
channel
=
Me
();
using
(
var
muxerA
=
Create
())
...
...
@@ -542,11 +536,10 @@ public void TestPublishWithSubscribers()
var
t1
=
listenA
.
SubscribeAsync
(
channel
,
delegate
{
});
var
t2
=
listenB
.
SubscribeAsync
(
channel
,
delegate
{
});
listenA
.
Wait
(
t1
);
listenB
.
Wait
(
t2
);
await
Task
.
WhenAll
(
t1
,
t2
).
ForAwait
();
var
pub
=
conn
.
GetSubscriber
().
PublishAsync
(
channel
,
"message"
);
Assert
.
Equal
(
2
,
conn
.
Wait
(
pub
)
);
// delivery count
Assert
.
Equal
(
2
,
await
pub
);
// delivery count
}
}
...
...
@@ -563,10 +556,9 @@ public async Task TestMultipleSubscribersGetMessage()
conn
.
GetDatabase
().
Ping
();
var
pub
=
conn
.
GetSubscriber
();
int
gotA
=
0
,
gotB
=
0
;
var
tA
=
listenA
.
SubscribeAsync
(
channel
,
(
s
,
msg
)
=>
{
if
(
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotA
);
});
var
tB
=
listenB
.
SubscribeAsync
(
channel
,
(
s
,
msg
)
=>
{
if
(
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotB
);
});
listenA
.
Wait
(
tA
);
listenB
.
Wait
(
tB
);
var
tA
=
listenA
.
SubscribeAsync
(
channel
,
(
_
,
msg
)
=>
{
if
(
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotA
);
});
var
tB
=
listenB
.
SubscribeAsync
(
channel
,
(
_
,
msg
)
=>
{
if
(
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotB
);
});
await
Task
.
WhenAll
(
tA
,
tB
).
ForAwait
();
Assert
.
Equal
(
2
,
pub
.
Publish
(
channel
,
"message"
));
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
1
,
Interlocked
.
CompareExchange
(
ref
gotA
,
0
,
0
));
...
...
@@ -574,7 +566,7 @@ public async Task TestMultipleSubscribersGetMessage()
// and unsubscibe...
tA
=
listenA
.
UnsubscribeAsync
(
channel
);
listenA
.
Wait
(
tA
)
;
await
tA
;
Assert
.
Equal
(
1
,
pub
.
Publish
(
channel
,
"message"
));
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
1
,
Interlocked
.
CompareExchange
(
ref
gotA
,
0
,
0
));
...
...
@@ -596,14 +588,14 @@ public async Task Issue38()
var
a1
=
sub
.
SubscribeAsync
(
prefix
+
"bar"
,
handler
);
var
b0
=
sub
.
SubscribeAsync
(
prefix
+
"f*o"
,
handler
);
var
b1
=
sub
.
SubscribeAsync
(
prefix
+
"b*r"
,
handler
);
sub
.
WaitAll
(
a0
,
a1
,
b0
,
b1
);
await
Task
.
WhenAll
(
a0
,
a1
,
b0
,
b1
).
ForAwait
(
);
var
c
=
sub
.
PublishAsync
(
prefix
+
"foo"
,
"foo"
);
var
d
=
sub
.
PublishAsync
(
prefix
+
"f@o"
,
"f@o"
);
var
e
=
sub
.
PublishAsync
(
prefix
+
"bar"
,
"bar"
);
var
f
=
sub
.
PublishAsync
(
prefix
+
"b@r"
,
"b@r"
);
await
Task
.
WhenAll
(
c
,
d
,
e
,
f
).
ForAwait
();
pub
.
WaitAll
(
c
,
d
,
e
,
f
);
long
total
=
c
.
Result
+
d
.
Result
+
e
.
Result
+
f
.
Result
;
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
...
...
@@ -629,8 +621,7 @@ public async Task TestPartialSubscriberGetMessage()
var
prefix
=
Me
();
var
tA
=
listenA
.
SubscribeAsync
(
prefix
+
"channel"
,
(
s
,
msg
)
=>
{
if
(
s
==
prefix
+
"channel"
&&
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotA
);
});
var
tB
=
listenB
.
SubscribeAsync
(
prefix
+
"chann*"
,
(
s
,
msg
)
=>
{
if
(
s
==
prefix
+
"channel"
&&
msg
==
"message"
)
Interlocked
.
Increment
(
ref
gotB
);
});
listenA
.
Wait
(
tA
);
listenB
.
Wait
(
tB
);
await
Task
.
WhenAll
(
tA
,
tB
).
ForAwait
();
Assert
.
Equal
(
2
,
pub
.
Publish
(
prefix
+
"channel"
,
"message"
));
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
1
,
Interlocked
.
CompareExchange
(
ref
gotA
,
0
,
0
));
...
...
@@ -638,7 +629,7 @@ public async Task TestPartialSubscriberGetMessage()
// and unsubscibe...
tB
=
listenB
.
UnsubscribeAsync
(
prefix
+
"chann*"
,
null
);
listenB
.
Wait
(
tB
)
;
await
tB
;
Assert
.
Equal
(
1
,
pub
.
Publish
(
prefix
+
"channel"
,
"message"
));
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
2
,
Interlocked
.
CompareExchange
(
ref
gotA
,
0
,
0
));
...
...
@@ -658,20 +649,20 @@ public async Task TestSubscribeUnsubscribeAndSubscribeAgain()
int
x
=
0
,
y
=
0
;
var
t1
=
sub
.
SubscribeAsync
(
prefix
+
"abc"
,
delegate
{
Interlocked
.
Increment
(
ref
x
);
});
var
t2
=
sub
.
SubscribeAsync
(
prefix
+
"ab*"
,
delegate
{
Interlocked
.
Increment
(
ref
y
);
});
sub
.
WaitAll
(
t1
,
t2
);
await
Task
.
WhenAll
(
t1
,
t2
).
ForAwait
(
);
pub
.
Publish
(
prefix
+
"abc"
,
""
);
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
1
,
Volatile
.
Read
(
ref
x
));
Assert
.
Equal
(
1
,
Volatile
.
Read
(
ref
y
));
t1
=
sub
.
UnsubscribeAsync
(
prefix
+
"abc"
,
null
);
t2
=
sub
.
UnsubscribeAsync
(
prefix
+
"ab*"
,
null
);
sub
.
WaitAll
(
t1
,
t2
);
await
Task
.
WhenAll
(
t1
,
t2
).
ForAwait
(
);
pub
.
Publish
(
prefix
+
"abc"
,
""
);
Assert
.
Equal
(
1
,
Volatile
.
Read
(
ref
x
));
Assert
.
Equal
(
1
,
Volatile
.
Read
(
ref
y
));
t1
=
sub
.
SubscribeAsync
(
prefix
+
"abc"
,
delegate
{
Interlocked
.
Increment
(
ref
x
);
});
t2
=
sub
.
SubscribeAsync
(
prefix
+
"ab*"
,
delegate
{
Interlocked
.
Increment
(
ref
y
);
});
sub
.
WaitAll
(
t1
,
t2
);
await
Task
.
WhenAll
(
t1
,
t2
).
ForAwait
(
);
pub
.
Publish
(
prefix
+
"abc"
,
""
);
await
AllowReasonableTimeToPublishAndProcess
().
ForAwait
();
Assert
.
Equal
(
2
,
Volatile
.
Read
(
ref
x
));
...
...
StackExchange.Redis.Tests/SSDB.cs
View file @
9e878625
...
...
@@ -21,9 +21,9 @@ public void ConnectToSSDB()
using
(
var
conn
=
ConnectionMultiplexer
.
Connect
(
config
))
{
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
Assert
.
True
(
db
.
StringGet
(
key
).
IsNull
);
db
.
StringSet
(
key
,
"abc"
);
db
.
StringSet
(
key
,
"abc"
,
flags
:
CommandFlags
.
FireAndForget
);
Assert
.
Equal
(
"abc"
,
db
.
StringGet
(
key
));
}
}
...
...
StackExchange.Redis.Tests/SSL.cs
View file @
9e878625
...
...
@@ -105,7 +105,7 @@ public async Task ConnectToSSLServer(bool useSsl, bool specifyHost)
muxer
.
ConnectionFailed
+=
OnConnectionFailed
;
muxer
.
InternalError
+=
OnInternalError
;
var
db
=
muxer
.
GetDatabase
();
await
db
.
PingAsync
();
await
db
.
PingAsync
()
.
ForAwait
()
;
using
(
var
file
=
File
.
Create
(
"ssl-"
+
useSsl
+
"-"
+
specifyHost
+
".zip"
))
{
muxer
.
ExportConfiguration
(
file
);
...
...
@@ -114,13 +114,13 @@ public async Task ConnectToSSLServer(bool useSsl, bool specifyHost)
const
int
AsyncLoop
=
2000
;
// perf; async
await
db
.
KeyDeleteAsync
(
key
);
await
db
.
KeyDeleteAsync
(
key
)
.
ForAwait
()
;
var
watch
=
Stopwatch
.
StartNew
();
for
(
int
i
=
0
;
i
<
AsyncLoop
;
i
++)
{
try
{
await
db
.
StringIncrementAsync
(
key
,
flags
:
CommandFlags
.
FireAndForget
);
await
db
.
StringIncrementAsync
(
key
,
flags
:
CommandFlags
.
FireAndForget
)
.
ForAwait
()
;
}
catch
(
Exception
ex
)
{
...
...
@@ -129,7 +129,7 @@ public async Task ConnectToSSLServer(bool useSsl, bool specifyHost)
}
}
// need to do this inside the timer to measure the TTLB
long
value
=
(
long
)
await
db
.
StringGetAsync
(
key
);
long
value
=
(
long
)
await
db
.
StringGetAsync
(
key
)
.
ForAwait
()
;
watch
.
Stop
();
Assert
.
Equal
(
AsyncLoop
,
value
);
Log
(
"F&F: {0} INCR, {1:###,##0}ms, {2} ops/s; final value: {3}"
,
...
...
@@ -173,7 +173,6 @@ public void RedisLabsSSL()
Skip
.
IfNoConfig
(
nameof
(
TestConfig
.
Config
.
RedisLabsSslServer
),
TestConfig
.
Current
.
RedisLabsSslServer
);
Skip
.
IfNoConfig
(
nameof
(
TestConfig
.
Config
.
RedisLabsPfxPath
),
TestConfig
.
Current
.
RedisLabsPfxPath
);
var
cert
=
new
X509Certificate2
(
TestConfig
.
Current
.
RedisLabsPfxPath
,
""
);
Assert
.
NotNull
(
cert
);
Writer
.
WriteLine
(
"Thumbprint: "
+
cert
.
Thumbprint
);
...
...
@@ -189,10 +188,8 @@ public void RedisLabsSSL()
"subscribe"
,
"unsubscribe"
,
"cluster"
},
false
)
};
options
.
TrustIssuer
(
"redislabs_ca.pem"
);
options
.
TrustIssuer
(
"redislabs_ca.pem"
);
if
(!
Directory
.
Exists
(
Me
()))
Directory
.
CreateDirectory
(
Me
());
#if LOGOUTPUT
...
...
@@ -207,10 +204,10 @@ public void RedisLabsSSL()
using
(
var
conn
=
ConnectionMultiplexer
.
Connect
(
options
))
{
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
string
s
=
db
.
StringGet
(
key
);
Assert
.
Null
(
s
);
db
.
StringSet
(
key
,
"abc"
);
db
.
StringSet
(
key
,
"abc"
,
flags
:
CommandFlags
.
FireAndForget
);
s
=
db
.
StringGet
(
key
);
Assert
.
Equal
(
"abc"
,
s
);
...
...
@@ -253,7 +250,7 @@ public void RedisLabsEnvironmentVariableClientCertificate(bool setEnv)
"subscribe"
,
"unsubscribe"
,
"cluster"
},
false
)
};
if
(!
Directory
.
Exists
(
Me
()))
Directory
.
CreateDirectory
(
Me
());
#if LOGOUTPUT
ConnectionMultiplexer
.
EchoPath
=
Me
();
...
...
@@ -265,7 +262,7 @@ public void RedisLabsEnvironmentVariableClientCertificate(bool setEnv)
if
(!
setEnv
)
Assert
.
True
(
false
,
"Could not set environment"
);
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
string
s
=
db
.
StringGet
(
key
);
Assert
.
Null
(
s
);
db
.
StringSet
(
key
,
"abc"
);
...
...
StackExchange.Redis.Tests/Scans.cs
View file @
9e878625
...
...
@@ -183,11 +183,11 @@ public void SetScan(bool supported)
{
RedisKey
key
=
Me
();
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"a"
);
db
.
SetAdd
(
key
,
"b"
);
db
.
SetAdd
(
key
,
"c"
);
db
.
SetAdd
(
key
,
"a"
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"b"
,
CommandFlags
.
FireAndForget
);
db
.
SetAdd
(
key
,
"c"
,
CommandFlags
.
FireAndForget
);
var
arr
=
db
.
SetScan
(
key
).
ToArray
();
Assert
.
Equal
(
3
,
arr
.
Length
);
Assert
.
True
(
arr
.
Contains
(
"a"
),
"a"
);
...
...
@@ -206,11 +206,11 @@ public void SortedSetScan(bool supported)
{
RedisKey
key
=
Me
()
+
supported
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
"a"
,
1
);
db
.
SortedSetAdd
(
key
,
"b"
,
2
);
db
.
SortedSetAdd
(
key
,
"c"
,
3
);
db
.
SortedSetAdd
(
key
,
"a"
,
1
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
"b"
,
2
,
CommandFlags
.
FireAndForget
);
db
.
SortedSetAdd
(
key
,
"c"
,
3
,
CommandFlags
.
FireAndForget
);
var
arr
=
db
.
SortedSetScan
(
key
).
ToArray
();
Assert
.
Equal
(
3
,
arr
.
Length
);
...
...
@@ -274,11 +274,11 @@ public void HashScan(bool supported)
{
RedisKey
key
=
Me
();
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
"a"
,
"1"
);
db
.
HashSet
(
key
,
"b"
,
"2"
);
db
.
HashSet
(
key
,
"c"
,
"3"
);
db
.
HashSet
(
key
,
"a"
,
"1"
,
flags
:
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
"b"
,
"2"
,
flags
:
CommandFlags
.
FireAndForget
);
db
.
HashSet
(
key
,
"c"
,
"3"
,
flags
:
CommandFlags
.
FireAndForget
);
var
arr
=
db
.
HashScan
(
key
).
ToArray
();
Assert
.
Equal
(
3
,
arr
.
Length
);
...
...
@@ -315,7 +315,7 @@ public void HashScanLarge(int pageSize)
{
RedisKey
key
=
Me
()
+
pageSize
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
0
;
i
<
2000
;
i
++)
db
.
HashSet
(
key
,
"k"
+
i
,
"v"
+
i
,
flags
:
CommandFlags
.
FireAndForget
);
...
...
@@ -342,14 +342,14 @@ public void HashScanThresholds()
private
bool
GotCursors
(
ConnectionMultiplexer
conn
,
RedisKey
key
,
int
count
)
{
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
var
entries
=
new
HashEntry
[
count
];
for
(
var
i
=
0
;
i
<
count
;
i
++)
{
entries
[
i
]
=
new
HashEntry
(
"Item:"
+
i
,
i
);
}
db
.
HashSet
(
key
,
entries
);
db
.
HashSet
(
key
,
entries
,
CommandFlags
.
FireAndForget
);
var
found
=
false
;
var
response
=
db
.
HashScan
(
key
);
...
...
@@ -375,7 +375,7 @@ public void SetScanLarge(int pageSize)
{
RedisKey
key
=
Me
()
+
pageSize
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
0
;
i
<
2000
;
i
++)
db
.
SetAdd
(
key
,
"s"
+
i
,
flags
:
CommandFlags
.
FireAndForget
);
...
...
@@ -396,7 +396,7 @@ public void SortedSetScanLarge(int pageSize)
{
RedisKey
key
=
Me
()
+
pageSize
;
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
0
;
i
<
2000
;
i
++)
db
.
SortedSetAdd
(
key
,
"z"
+
i
,
i
,
flags
:
CommandFlags
.
FireAndForget
);
...
...
StackExchange.Redis.Tests/Scripting.cs
View file @
9e878625
This diff is collapsed.
Click to expand it.
StackExchange.Redis.Tests/Sets.cs
View file @
9e878625
...
...
@@ -19,15 +19,14 @@ public void SScan()
RedisKey
key
=
Me
();
var
db
=
conn
.
GetDatabase
();
db
.
KeyDelete
(
key
);
int
totalUnfiltered
=
0
,
totalFiltered
=
0
;
for
(
int
i
=
0
;
i
<
1000
;
i
++)
for
(
int
i
=
1
;
i
<
1001
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
totalUnfiltered
+=
i
;
if
(
i
.
ToString
().
Contains
(
"3"
))
totalFiltered
+=
i
;
}
var
unfilteredActual
=
db
.
SetScan
(
key
).
Select
(
x
=>
(
int
)
x
).
Sum
();
Assert
.
Equal
(
totalUnfiltered
,
unfilteredActual
);
if
(
server
.
Features
.
Scan
)
...
...
@@ -47,12 +46,12 @@ public async Task SetRemoveArgTests()
var
key
=
Me
();
RedisValue
[]
values
=
null
;
Assert
.
Throws
<
ArgumentNullException
>(()
=>
db
.
SetRemove
(
key
,
values
,
CommandFlags
.
HighPriority
));
await
Assert
.
ThrowsAsync
<
ArgumentNullException
>(
async
()
=>
await
db
.
SetRemoveAsync
(
key
,
values
,
CommandFlags
.
HighPriority
).
ForAwait
()).
ForAwait
();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
db
.
SetRemove
(
key
,
values
));
await
Assert
.
ThrowsAsync
<
ArgumentNullException
>(
async
()
=>
await
db
.
SetRemoveAsync
(
key
,
values
).
ForAwait
()).
ForAwait
();
values
=
new
RedisValue
[
0
];
Assert
.
Equal
(
0
,
db
.
SetRemove
(
key
,
values
,
CommandFlags
.
HighPriority
));
Assert
.
Equal
(
0
,
await
db
.
SetRemoveAsync
(
key
,
values
,
CommandFlags
.
HighPriority
).
ForAwait
());
Assert
.
Equal
(
0
,
db
.
SetRemove
(
key
,
values
));
Assert
.
Equal
(
0
,
await
db
.
SetRemoveAsync
(
key
,
values
).
ForAwait
());
}
}
...
...
@@ -66,10 +65,10 @@ public void SetPopMulti_Multi()
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
1
;
i
<
11
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
Async
(
key
,
i
,
CommandFlags
.
FireAndForget
);
}
var
random
=
db
.
SetPop
(
key
);
...
...
@@ -92,10 +91,10 @@ public void SetPopMulti_Single()
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
1
;
i
<
11
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
}
var
random
=
db
.
SetPop
(
key
);
...
...
@@ -121,10 +120,10 @@ public async Task SetPopMulti_Multi_Async()
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
1
;
i
<
11
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
}
var
random
=
await
db
.
SetPopAsync
(
key
).
ForAwait
();
...
...
@@ -148,10 +147,10 @@ public async Task SetPopMulti_Single_Async()
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
1
;
i
<
11
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
}
var
random
=
await
db
.
SetPopAsync
(
key
).
ForAwait
();
...
...
@@ -175,10 +174,10 @@ public async Task SetPopMulti_Zero_Async()
var
db
=
conn
.
GetDatabase
();
var
key
=
Me
();
db
.
KeyDelete
(
key
);
db
.
KeyDelete
(
key
,
CommandFlags
.
FireAndForget
);
for
(
int
i
=
1
;
i
<
11
;
i
++)
{
db
.
SetAdd
(
key
,
i
);
db
.
SetAdd
(
key
,
i
,
CommandFlags
.
FireAndForget
);
}
var
t
=
db
.
SetPopAsync
(
key
,
count
:
0
);
...
...
StackExchange.Redis.Tests/Strings.cs
View file @
9e878625
This diff is collapsed.
Click to expand it.
StackExchange.Redis.Tests/TestBase.cs
View file @
9e878625
...
...
@@ -47,11 +47,9 @@ protected void Log(string message, params object[] args)
protected
void
CollectGarbage
()
{
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
);
GC
.
WaitForPendingFinalizers
();
}
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
);
GC
.
WaitForPendingFinalizers
();
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
);
}
[
System
.
Diagnostics
.
CodeAnalysis
.
SuppressMessage
(
"Microsoft.Design"
,
"CA1063:ImplementIDisposableCorrectly"
)]
...
...
@@ -63,7 +61,7 @@ public void Dispose()
#if VERBOSE
protected
const
int
AsyncOpsQty
=
100
,
SyncOpsQty
=
10
;
#else
protected
const
int
AsyncOpsQty
=
10000
0
,
SyncOpsQty
=
10000
;
protected
const
int
AsyncOpsQty
=
10000
,
SyncOpsQty
=
10000
;
#endif
static
TestBase
()
...
...
@@ -91,7 +89,7 @@ protected void OnConnectionFailed(object sender, ConnectionFailedEventArgs e)
Interlocked
.
Increment
(
ref
privateFailCount
);
lock
(
privateExceptions
)
{
privateExceptions
.
Add
(
"Connection failed: "
+
EndPointCollection
.
ToString
(
e
.
EndPoint
)
+
"/"
+
e
.
ConnectionType
);
privateExceptions
.
Add
(
$"Connection failed (
{
e
.
FailureType
}
):
{
EndPointCollection
.
ToString
(
e
.
EndPoint
)}
/
{
e
.
ConnectionType
}
:
{
e
.
Exception
}
"
);
}
}
...
...
@@ -113,7 +111,6 @@ protected void OnInternalError(object sender, InternalErrorEventArgs e)
public
void
ClearAmbientFailures
()
{
Collect
();
Interlocked
.
Exchange
(
ref
privateFailCount
,
0
);
lock
(
sharedFailCount
)
{
...
...
@@ -135,18 +132,8 @@ public void SetExpectedAmbientFailureCount(int count)
expectedFailCount
=
count
;
}
private
static
void
Collect
()
{
for
(
int
i
=
0
;
i
<
GC
.
MaxGeneration
;
i
++)
{
GC
.
Collect
(
GC
.
MaxGeneration
,
GCCollectionMode
.
Forced
,
true
);
GC
.
WaitForPendingFinalizers
();
}
}
public
void
Teardown
()
{
Collect
();
int
sharedFails
;
lock
(
sharedFailCount
)
{
...
...
StackExchange.Redis.Tests/Transactions.cs
View file @
9e878625
This diff is collapsed.
Click to expand it.
StackExchange.Redis.Tests/WithKeyPrefixTests.cs
View file @
9e878625
...
...
@@ -7,7 +7,7 @@ namespace StackExchange.Redis.Tests
{
public
class
WithKeyPrefixTests
:
TestBase
{
public
WithKeyPrefixTests
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
public
WithKeyPrefixTests
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
[
Fact
]
public
void
BlankPrefixYieldsSame_Bytes
()
...
...
@@ -34,7 +34,8 @@ public void BlankPrefixYieldsSame_String()
[
Fact
]
public
void
NullPrefixIsError_Bytes
()
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
using
(
var
conn
=
Create
())
{
var
raw
=
conn
.
GetDatabase
();
...
...
@@ -46,7 +47,8 @@ public void NullPrefixIsError_Bytes()
[
Fact
]
public
void
NullPrefixIsError_String
()
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
using
(
var
conn
=
Create
())
{
var
raw
=
conn
.
GetDatabase
();
...
...
@@ -61,7 +63,8 @@ public void NullPrefixIsError_String()
[
InlineData
(
null
)]
public
void
NullDatabaseIsError
(
string
prefix
)
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
{
IDatabase
raw
=
null
;
var
prefixed
=
raw
.
WithKeyPrefix
(
prefix
);
});
...
...
@@ -70,7 +73,7 @@ public void NullDatabaseIsError(string prefix)
[
Fact
]
public
void
BasicSmokeTest
()
{
using
(
var
conn
=
Create
())
using
(
var
conn
=
Create
())
{
var
raw
=
conn
.
GetDatabase
();
...
...
@@ -82,11 +85,11 @@ public void BasicSmokeTest()
string
s
=
Guid
.
NewGuid
().
ToString
(),
t
=
Guid
.
NewGuid
().
ToString
();
foo
.
StringSet
(
key
,
s
);
foo
.
StringSet
(
key
,
s
,
flags
:
CommandFlags
.
FireAndForget
);
var
val
=
(
string
)
foo
.
StringGet
(
key
);
Assert
.
Equal
(
s
,
val
);
// fooBasicSmokeTest
foobar
.
StringSet
(
key
,
t
);
foobar
.
StringSet
(
key
,
t
,
flags
:
CommandFlags
.
FireAndForget
);
val
=
(
string
)
foobar
.
StringGet
(
key
);
Assert
.
Equal
(
t
,
val
);
// foobarBasicSmokeTest
...
...
@@ -104,18 +107,18 @@ public void BasicSmokeTest()
[
Fact
]
public
void
ConditionTest
()
{
using
(
var
conn
=
Create
())
using
(
var
conn
=
Create
())
{
var
raw
=
conn
.
GetDatabase
();
var
prefix
=
Me
()
+
":"
;
var
foo
=
raw
.
WithKeyPrefix
(
prefix
);
raw
.
KeyDelete
(
prefix
+
"abc"
);
raw
.
KeyDelete
(
prefix
+
"i"
);
raw
.
KeyDelete
(
prefix
+
"abc"
,
CommandFlags
.
FireAndForget
);
raw
.
KeyDelete
(
prefix
+
"i"
,
CommandFlags
.
FireAndForget
);
// execute while key exists
raw
.
StringSet
(
prefix
+
"abc"
,
"def"
);
raw
.
StringSet
(
prefix
+
"abc"
,
"def"
,
flags
:
CommandFlags
.
FireAndForget
);
var
tran
=
foo
.
CreateTransaction
();
tran
.
AddCondition
(
Condition
.
KeyExists
(
"abc"
));
tran
.
StringIncrementAsync
(
"i"
);
...
...
@@ -125,7 +128,7 @@ public void ConditionTest()
Assert
.
Equal
(
1
,
i
);
// repeat without key
raw
.
KeyDelete
(
prefix
+
"abc"
);
raw
.
KeyDelete
(
prefix
+
"abc"
,
CommandFlags
.
FireAndForget
);
tran
=
foo
.
CreateTransaction
();
tran
.
AddCondition
(
Condition
.
KeyExists
(
"abc"
));
tran
.
StringIncrementAsync
(
"i"
);
...
...
StackExchange.Redis/StackExchange/Redis/CompletionManager.cs
View file @
9e878625
...
...
@@ -53,6 +53,6 @@ private static void AnyOrderCompletionHandler(object state)
{
ConnectionMultiplexer
.
TraceWithoutContext
(
"Async completion error: "
+
ex
.
Message
);
}
}
}
}
}
StackExchange.Redis/StackExchange/Redis/ConfigurationOptions.cs
View file @
9e878625
...
...
@@ -186,10 +186,13 @@ public static string TryNormalize(string value)
/// <summary>
/// Create a certificate validation check that checks against the supplied issuer even if not known by the machine
/// </summary>
/// <param name="issuerCertificatePath">The file system path to find the certificate at.</param>
public
void
TrustIssuer
(
string
issuerCertificatePath
)
=>
CertificateValidationCallback
=
TrustIssuerCallback
(
issuerCertificatePath
);
/// <summary>
/// Create a certificate validation check that checks against the supplied issuer even if not known by the machine
/// </summary>
/// <param name="issuer">The issuer to trust.</param>
public
void
TrustIssuer
(
X509Certificate2
issuer
)
=>
CertificateValidationCallback
=
TrustIssuerCallback
(
issuer
);
internal
static
RemoteCertificateValidationCallback
TrustIssuerCallback
(
string
issuerCertificatePath
)
...
...
@@ -202,7 +205,8 @@ private static RemoteCertificateValidationCallback TrustIssuerCallback(X509Certi
=>
sslPolicyError
==
SslPolicyErrors
.
RemoteCertificateChainErrors
&&
certificate
is
X509Certificate2
v2
&&
CheckTrustedIssuer
(
v2
,
issuer
);
}
static
bool
CheckTrustedIssuer
(
X509Certificate2
certificateToValidate
,
X509Certificate2
authority
)
private
static
bool
CheckTrustedIssuer
(
X509Certificate2
certificateToValidate
,
X509Certificate2
authority
)
{
// reference: https://stackoverflow.com/questions/6497040/how-do-i-validate-that-a-certificate-was-created-by-a-particular-certification-a
X509Chain
chain
=
new
X509Chain
();
...
...
@@ -215,7 +219,6 @@ static bool CheckTrustedIssuer(X509Certificate2 certificateToValidate, X509Certi
chain
.
ChainPolicy
.
ExtraStore
.
Add
(
authority
);
return
chain
.
Build
(
certificateToValidate
);
}
/// <summary>
/// The client name to use for all connections
...
...
@@ -729,14 +732,8 @@ private void DoParse(string configuration, bool ignoreUnknown)
}
}
private
bool
GetDefaultAbortOnConnectFailSetting
()
{
// Microsoft Azure team wants abortConnect=false by default
if
(
IsAzureEndpoint
())
return
false
;
return
true
;
}
// Microsoft Azure team wants abortConnect=false by default
private
bool
GetDefaultAbortOnConnectFailSetting
()
=>
!
IsAzureEndpoint
();
private
bool
IsAzureEndpoint
()
{
...
...
StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.cs
View file @
9e878625
...
...
@@ -452,7 +452,7 @@ internal void CheckMessage(Message message)
throw
ExceptionFactory
.
AdminModeNotEnabled
(
IncludeDetailInExceptions
,
message
.
Command
,
message
,
null
);
CommandMap
.
AssertAvailable
(
message
.
Command
);
}
const
string
NoContent
=
"(no content)"
;
private
const
string
NoContent
=
"(no content)"
;
private
static
void
WriteNormalizingLineEndings
(
string
source
,
StreamWriter
writer
)
{
if
(
source
==
null
)
...
...
@@ -645,8 +645,10 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
}
var
allTasks
=
Task
.
WhenAll
(
tasks
).
ObserveErrors
();
var
any
=
Task
.
WhenAny
(
allTasks
,
Task
.
Delay
(
remaining
)).
ObserveErrors
();
var
cts
=
new
CancellationTokenSource
();
var
any
=
Task
.
WhenAny
(
allTasks
,
Task
.
Delay
(
remaining
,
cts
.
Token
)).
ObserveErrors
();
bool
all
=
await
any
.
ForAwait
()
==
allTasks
;
cts
.
Cancel
();
LogLockedWithThreadPoolStats
(
log
,
all
?
"All tasks completed cleanly"
:
$"Not all tasks completed cleanly (from
{
caller
}
#
{
callerLineNumber
}
, timeout
{
timeoutMilliseconds
}
ms)"
,
out
busyWorkerCount
);
return
all
;
}
...
...
@@ -798,13 +800,13 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration)
{
if
(
configuration
==
null
)
throw
new
ArgumentNullException
(
nameof
(
configuration
));
ConfigurationOptions
config
;
if
(
configuration
is
string
)
if
(
configuration
is
string
s
)
{
config
=
ConfigurationOptions
.
Parse
(
(
string
)
configuration
);
config
=
ConfigurationOptions
.
Parse
(
s
);
}
else
if
(
configuration
is
ConfigurationOptions
)
else
if
(
configuration
is
ConfigurationOptions
configurationOptions
)
{
config
=
(
(
ConfigurationOptions
)
configuration
).
Clone
();
config
=
(
configurationOptions
).
Clone
();
}
else
{
...
...
@@ -871,7 +873,7 @@ private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> mul
private
readonly
Hashtable
servers
=
new
Hashtable
();
private
volatile
ServerSnapshot
_serverSnapshot
=
ServerSnapshot
.
Empty
;
internal
ReadOnlySpan
<
ServerEndPoint
>
GetServerSnapshot
()
=>
_serverSnapshot
.
Span
;
sealed
class
ServerSnapshot
private
sealed
class
ServerSnapshot
{
public
static
ServerSnapshot
Empty
{
get
;
}
=
new
ServerSnapshot
(
Array
.
Empty
<
ServerEndPoint
>(),
0
);
private
ServerSnapshot
(
ServerEndPoint
[]
arr
,
int
count
)
...
...
@@ -879,8 +881,8 @@ private ServerSnapshot(ServerEndPoint[] arr, int count)
_arr
=
arr
;
_count
=
count
;
}
private
ServerEndPoint
[]
_arr
;
private
int
_count
;
private
readonly
ServerEndPoint
[]
_arr
;
private
readonly
int
_count
;
public
ReadOnlySpan
<
ServerEndPoint
>
Span
=>
new
ReadOnlySpan
<
ServerEndPoint
>(
_arr
,
0
,
_count
);
internal
ServerSnapshot
Add
(
ServerEndPoint
value
)
...
...
@@ -1293,11 +1295,13 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
{
if
(
configuration
.
ResolveDns
&&
configuration
.
HasDnsEndPoints
())
{
var
cts
=
new
CancellationTokenSource
();
var
dns
=
configuration
.
ResolveEndPointsAsync
(
this
,
log
).
ObserveErrors
();
if
((
await
Task
.
WhenAny
(
dns
,
Task
.
Delay
(
TimeoutMilliseconds
)).
ForAwait
())
!=
dns
)
if
((
await
Task
.
WhenAny
(
dns
,
Task
.
Delay
(
TimeoutMilliseconds
,
cts
.
Token
)).
ForAwait
())
!=
dns
)
{
throw
new
TimeoutException
(
"Timeout resolving endpoints"
);
}
cts
.
Cancel
();
}
foreach
(
var
endpoint
in
configuration
.
EndPoints
)
{
...
...
@@ -2251,8 +2255,10 @@ public Task<long> PublishReconfigureAsync(CommandFlags flags = CommandFlags.None
/// <summary>
/// Get the hash-slot associated with a given key, if applicable; this can be useful for grouping operations
/// </summary>
/// <param name="key">The <see cref="RedisKey"/> to determine the hash slot for.</param>
public
int
GetHashSlot
(
RedisKey
key
)
=>
ServerSelectionStrategy
.
HashSlot
(
key
);
}
internal
enum
WriteResult
{
Success
,
...
...
StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs
View file @
9e878625
...
...
@@ -831,13 +831,13 @@ protected ICollection<object> ToInner(ICollection<object> args)
foreach
(
var
oldArg
in
args
)
{
object
newArg
;
if
(
oldArg
is
RedisKey
)
if
(
oldArg
is
RedisKey
key
)
{
newArg
=
ToInner
(
(
RedisKey
)
oldArg
);
newArg
=
ToInner
(
key
);
}
else
if
(
oldArg
is
RedisChannel
)
else
if
(
oldArg
is
RedisChannel
channel
)
{
newArg
=
ToInner
(
(
RedisChannel
)
oldArg
);
newArg
=
ToInner
(
channel
);
}
else
{
...
...
StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs
View file @
9e878625
...
...
@@ -547,7 +547,7 @@ internal WriteResult WriteMessageTakingWriteLock(PhysicalConnection physical, Me
{
result
=
WriteMessageToServerInsideWriteLock
(
physical
,
next
);
}
physical
.
WakeWriterAndCheckForThrottle
();
result
=
physical
.
WakeWriterAndCheckForThrottle
();
}
finally
{
...
...
StackExchange.Redis/StackExchange/Redis/PhysicalConnection.cs
View file @
9e878625
...
...
@@ -106,11 +106,12 @@ internal async void BeginConnectAsync(TextWriter log)
RemoteEndPoint
=
endpoint
,
};
_socketArgs
.
Completed
+=
SocketAwaitable
.
Callback
;
CancellationTokenSource
timeoutSource
=
null
;
try
{
if
(
_socket
.
ConnectAsync
(
_socketArgs
))
{
// asynchronous operation is pending
ConfigureTimeout
(
_socketArgs
,
Multiplexer
.
RawConfig
.
ConnectTimeout
);
timeoutSource
=
ConfigureTimeout
(
_socketArgs
,
Multiplexer
.
RawConfig
.
ConnectTimeout
);
}
else
{
// completed synchronously
...
...
@@ -125,6 +126,7 @@ internal async void BeginConnectAsync(TextWriter log)
if
(
ignoreConnect
)
return
;
await
awaitable
;
// wait for the connect to complete or fail (will throw)
timeoutSource
?.
Cancel
();
if
(
await
ConnectedAsync
(
_socket
,
log
,
Multiplexer
.
SocketManager
).
ForAwait
())
{
...
...
@@ -175,9 +177,10 @@ internal async void BeginConnectAsync(TextWriter log)
}
}
private
static
void
ConfigureTimeout
(
SocketAsyncEventArgs
args
,
int
timeoutMilliseconds
)
private
static
CancellationTokenSource
ConfigureTimeout
(
SocketAsyncEventArgs
args
,
int
timeoutMilliseconds
)
{
var
timeout
=
Task
.
Delay
(
timeoutMilliseconds
);
var
cts
=
new
CancellationTokenSource
();
var
timeout
=
Task
.
Delay
(
timeoutMilliseconds
,
cts
.
Token
);
timeout
.
ContinueWith
((
_
,
state
)
=>
{
try
...
...
@@ -190,6 +193,7 @@ private static void ConfigureTimeout(SocketAsyncEventArgs args, int timeoutMilli
}
catch
{
}
},
args
);
return
cts
;
}
private
enum
ReadMode
:
byte
...
...
@@ -720,17 +724,18 @@ internal static int WriteRaw(Span<byte> span, long value, bool withLengthPrefix
return
WriteCrlf
(
span
,
offset
);
}
internal
void
WakeWriterAndCheckForThrottle
()
internal
WriteResult
WakeWriterAndCheckForThrottle
()
{
try
{
var
flush
=
_ioPipe
.
Output
.
FlushAsync
();
if
(!
flush
.
IsCompletedSuccessfully
)
flush
.
AsTask
().
Wait
();
return
WriteResult
.
Success
;
}
catch
(
ConnectionResetException
ex
)
{
RecordConnectionFailed
(
ConnectionFailureType
.
SocketClosed
,
ex
);
throw
;
return
WriteResult
.
WriteFailure
;
}
}
...
...
StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs
View file @
9e878625
...
...
@@ -2638,7 +2638,7 @@ private Message GetStreamAddMessage(RedisKey key, RedisValue messageId, int? max
var
offset
=
0
;
values
[
offset
++]
=
messageId
;
if
(
maxLength
.
HasValue
)
{
values
[
offset
++]
=
StreamConstants
.
MaxLen
;
...
...
@@ -3060,7 +3060,7 @@ public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max,
public
RedisValue
[]
SortedSetRangeByValue
(
RedisKey
key
,
RedisValue
min
,
RedisValue
max
,
Exclude
exclude
,
long
skip
,
long
take
,
CommandFlags
flags
)
=>
SortedSetRangeByValue
(
key
,
min
,
max
,
exclude
,
Order
.
Ascending
,
skip
,
take
,
flags
);
static
void
ReverseLimits
(
Order
order
,
ref
Exclude
exclude
,
ref
RedisValue
start
,
ref
RedisValue
stop
)
private
static
void
ReverseLimits
(
Order
order
,
ref
Exclude
exclude
,
ref
RedisValue
start
,
ref
RedisValue
stop
)
{
bool
reverseLimits
=
(
order
==
Order
.
Ascending
)
==
start
.
CompareTo
(
stop
)
>
0
;
if
(
reverseLimits
)
...
...
@@ -3097,6 +3097,7 @@ public Task<long> SortedSetLengthByValueAsync(RedisKey key, RedisValue min, Redi
public
Task
<
RedisValue
[
]>
SortedSetRangeByValueAsync
(
RedisKey
key
,
RedisValue
min
,
RedisValue
max
,
Exclude
exclude
,
long
skip
,
long
take
,
CommandFlags
flags
)
=>
SortedSetRangeByValueAsync
(
key
,
min
,
max
,
exclude
,
Order
.
Ascending
,
skip
,
take
,
flags
);
public
Task
<
RedisValue
[
]>
SortedSetRangeByValueAsync
(
RedisKey
key
,
RedisValue
min
=
default
(
RedisValue
),
RedisValue
max
=
default
(
RedisValue
),
Exclude
exclude
=
Exclude
.
None
,
Order
order
=
Order
.
Ascending
,
long
skip
=
0
,
long
take
=
-
1
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
...
...
@@ -3124,7 +3125,7 @@ internal class ScanIterator<T> : CursorEnumerable<T>
this
.
key
=
key
;
this
.
pattern
=
pattern
;
this
.
command
=
command
;
this
.
Processor
=
processor
;
Processor
=
processor
;
}
protected
override
ResultProcessor
<
CursorEnumerable
<
T
>.
ScanResult
>
Processor
{
get
;
}
...
...
@@ -3222,13 +3223,13 @@ protected override void WriteImpl(PhysicalConnection physical)
physical
.
WriteHeader
(
_command
,
args
.
Count
);
foreach
(
object
arg
in
args
)
{
if
(
arg
is
RedisKey
)
if
(
arg
is
RedisKey
key
)
{
physical
.
Write
(
(
RedisKey
)
arg
);
physical
.
Write
(
key
);
}
else
if
(
arg
is
RedisChannel
)
else
if
(
arg
is
RedisChannel
channel
)
{
physical
.
Write
(
(
RedisChannel
)
arg
);
physical
.
Write
(
channel
);
}
else
{
// recognises well-known types
...
...
@@ -3246,9 +3247,9 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
int
slot
=
ServerSelectionStrategy
.
NoSlot
;
foreach
(
object
arg
in
args
)
{
if
(
arg
is
RedisKey
)
if
(
arg
is
RedisKey
key
)
{
slot
=
serverSelectionStrategy
.
CombineSlot
(
slot
,
(
RedisKey
)
arg
);
slot
=
serverSelectionStrategy
.
CombineSlot
(
slot
,
key
);
}
}
return
slot
;
...
...
@@ -3260,7 +3261,9 @@ private sealed class ScriptEvalMessage : Message, IMultiMessage
private
readonly
RedisKey
[]
keys
;
private
readonly
string
script
;
private
readonly
RedisValue
[]
values
;
private
byte
[]
asciiHash
,
hexHash
;
private
byte
[]
asciiHash
;
private
readonly
byte
[]
hexHash
;
public
ScriptEvalMessage
(
int
db
,
CommandFlags
flags
,
string
script
,
RedisKey
[]
keys
,
RedisValue
[]
values
)
:
this
(
db
,
flags
,
ResultProcessor
.
ScriptLoadProcessor
.
IsSHA1
(
script
)
?
RedisCommand
.
EVALSHA
:
RedisCommand
.
EVAL
,
script
,
null
,
keys
,
values
)
{
...
...
StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs
View file @
9e878625
...
...
@@ -179,7 +179,7 @@ private class TransactionMessage : Message, IMultiMessage
public
TransactionMessage
(
int
db
,
CommandFlags
flags
,
List
<
ConditionResult
>
conditions
,
List
<
QueuedMessage
>
operations
)
:
base
(
db
,
flags
,
RedisCommand
.
EXEC
)
{
this
.
InnerOperations
=
(
operations
==
null
||
operations
.
Count
==
0
)
?
Array
.
Empty
<
QueuedMessage
>()
:
operations
.
ToArray
();
InnerOperations
=
(
operations
==
null
||
operations
.
Count
==
0
)
?
Array
.
Empty
<
QueuedMessage
>()
:
operations
.
ToArray
();
this
.
conditions
=
(
conditions
==
null
||
conditions
.
Count
==
0
)
?
Array
.
Empty
<
ConditionResult
>():
conditions
.
ToArray
();
}
...
...
StackExchange.Redis/StackExchange/Redis/RedisValue.cs
View file @
9e878625
...
...
@@ -644,7 +644,9 @@ private static string ToHex(ReadOnlySpan<byte> src)
if
(
MemoryMarshal
.
TryGetArray
(
value
.
_memory
,
out
var
segment
)
&&
segment
.
Offset
==
0
&&
segment
.
Count
==
(
segment
.
Array
?.
Length
??
-
1
))
{
return
segment
.
Array
;
// the memory is backed by an array, and we're reading all of it
}
return
value
.
_memory
.
ToArray
();
case
StorageType
.
Int64
:
...
...
@@ -738,8 +740,7 @@ private RedisValue Simplify()
case
StorageType
.
Double
:
// is the double actually an integer?
f64
=
OverlappedValueDouble
;
if
(
f64
>=
long
.
MinValue
&&
f64
<=
long
.
MaxValue
&&
(
i64
=
(
long
)
f64
)
==
f64
)
return
i64
;
if
(
f64
>=
long
.
MinValue
&&
f64
<=
long
.
MaxValue
&&
(
i64
=
(
long
)
f64
)
==
f64
)
return
i64
;
break
;
}
return
this
;
...
...
@@ -749,6 +750,7 @@ private RedisValue Simplify()
/// Create a RedisValue from a MemoryStream; it will *attempt* to use the internal buffer
/// directly, but if this isn't possibly it will fallback to ToArray
/// </summary>
/// <param name="stream">The <see cref="MemoryStream"/> to create a value from.</param>
public
static
RedisValue
CreateFrom
(
MemoryStream
stream
)
{
if
(
stream
==
null
)
return
Null
;
...
...
@@ -764,28 +766,28 @@ public static RedisValue CreateFrom(MemoryStream stream)
}
}
/// <summary>
/// Indicates whether the current value has the supplied value as a prefix
/// Indicates whether the current value has the supplied value as a prefix
.
/// </summary>
/// <param name="value">The <see cref="RedisValue"/> to check.</param>
public
bool
StartsWith
(
RedisValue
value
)
{
if
(
this
.
IsNull
||
value
.
IsNull
)
return
false
;
if
(
IsNull
||
value
.
IsNull
)
return
false
;
if
(
value
.
IsNullOrEmpty
)
return
true
;
if
(
this
.
IsNullOrEmpty
)
return
false
;
if
(
IsNullOrEmpty
)
return
false
;
ReadOnlyMemory
<
byte
>
rawThis
,
rawOther
;
var
thisType
=
this
.
Type
;
var
thisType
=
Type
;
if
(
thisType
==
value
.
Type
)
// same? can often optimize
{
switch
(
thisType
)
{
case
StorageType
.
String
:
var
sThis
=
((
string
)
this
.
_objectOrSentinel
);
var
sThis
=
((
string
)
_objectOrSentinel
);
var
sOther
=
((
string
)
value
.
_objectOrSentinel
);
return
sThis
.
StartsWith
(
sOther
,
StringComparison
.
Ordinal
);
case
StorageType
.
Raw
:
rawThis
=
this
.
_memory
;
rawThis
=
_memory
;
rawOther
=
value
.
_memory
;
return
rawThis
.
Span
.
StartsWith
(
rawOther
.
Span
);
}
...
...
@@ -793,7 +795,7 @@ public bool StartsWith(RedisValue value)
byte
[]
arr0
=
null
,
arr1
=
null
;
try
{
rawThis
=
this
.
AsMemory
(
out
arr0
);
rawThis
=
AsMemory
(
out
arr0
);
rawOther
=
value
.
AsMemory
(
out
arr1
);
return
rawThis
.
Span
.
StartsWith
(
rawOther
.
Span
);
...
...
@@ -830,7 +832,6 @@ private ReadOnlyMemory<byte> AsMemory(out byte[] leased)
leased
=
ArrayPool
<
byte
>.
Shared
.
Rent
(
PhysicalConnection
.
MaxInt64TextLen
+
2
);
// reused code has CRLF terminator
len
=
PhysicalConnection
.
WriteRaw
(
leased
,
_overlappedValue64
)
-
2
;
// drop the CRLF
return
new
ReadOnlyMemory
<
byte
>(
leased
,
0
,
len
);
}
leased
=
null
;
return
default
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment