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
ad0eb82c
Commit
ad0eb82c
authored
Mar 12, 2019
by
Marc Gravell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixing the last unanswered write time; number was garbage
parent
42b5a860
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
41 additions
and
31 deletions
+41
-31
ConnectionMultiplexer.cs
src/StackExchange.Redis/ConnectionMultiplexer.cs
+5
-2
Message.cs
src/StackExchange.Redis/Message.cs
+1
-0
PhysicalBridge.cs
src/StackExchange.Redis/PhysicalBridge.cs
+4
-6
PhysicalConnection.cs
src/StackExchange.Redis/PhysicalConnection.cs
+12
-7
RawResult.cs
src/StackExchange.Redis/RawResult.cs
+1
-1
RedisSubscriber.cs
src/StackExchange.Redis/RedisSubscriber.cs
+1
-2
ResultProcessor.cs
src/StackExchange.Redis/ResultProcessor.cs
+1
-1
ServerSelectionStrategy.cs
src/StackExchange.Redis/ServerSelectionStrategy.cs
+16
-12
No files found.
src/StackExchange.Redis/ConnectionMultiplexer.cs
View file @
ad0eb82c
...
...
@@ -742,9 +742,12 @@ private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilli
internal
void
OnHashSlotMoved
(
int
hashSlot
,
EndPoint
old
,
EndPoint
@new
)
{
var
handler
=
HashSlotMoved
;
if
(
handler
!=
null
)
ConnectionMultiplexer
.
CompleteAsWorker
(
if
(
handler
!=
null
)
{
ConnectionMultiplexer
.
CompleteAsWorker
(
new
HashSlotMovedEventArgs
(
handler
,
this
,
hashSlot
,
old
,
@new
));
}
}
/// <summary>
/// Compute the hash-slot of a specified key
...
...
src/StackExchange.Redis/Message.cs
View file @
ad0eb82c
...
...
@@ -666,6 +666,7 @@ internal void SetWriteTime()
}
}
private
int
_writeTickCount
;
public
int
GetWriteTime
()
=>
Volatile
.
Read
(
ref
_writeTickCount
);
private
void
SetNeedsTimeoutCheck
()
=>
Flags
|=
NeedsAsyncTimeoutCheckFlag
;
internal
bool
HasAsyncTimedOut
(
int
now
,
int
timeoutMilliseconds
,
out
int
millisecondsTaken
)
...
...
src/StackExchange.Redis/PhysicalBridge.cs
View file @
ad0eb82c
...
...
@@ -286,7 +286,7 @@ private void ShutdownSubscriptionQueue()
}
}
internal
bool
TryEnqueueBackgroundSubscriptionWrite
(
PendingSubscriptionState
state
)
internal
bool
TryEnqueueBackgroundSubscriptionWrite
(
in
PendingSubscriptionState
state
)
=>
isDisposed
?
false
:
(
_subscriptionBackgroundQueue
??
GetSubscriptionQueue
()).
Writer
.
TryWrite
(
state
);
internal
void
GetOutstandingCount
(
out
int
inst
,
out
int
qs
,
out
int
@in
,
out
int
qu
)
...
...
@@ -443,7 +443,6 @@ private void AbandonPendingBacklog(Exception ex)
Message
next
;
do
{
lock
(
_backlog
)
{
next
=
_backlog
.
Count
==
0
?
null
:
_backlog
.
Dequeue
();
...
...
@@ -737,11 +736,10 @@ private void StartBacklogProcessor()
sched
.
Schedule
(
s_ProcessBacklog
,
_weakRefThis
);
}
static
readonly
Action
<
object
>
s_ProcessBacklog
=
s
=>
private
static
readonly
Action
<
object
>
s_ProcessBacklog
=
s
=>
{
var
wr
=
(
WeakReference
)
s
;
var
bridge
=
wr
.
Target
as
PhysicalBridge
;
if
(
bridge
!=
null
)
bridge
.
ProcessBacklog
();
if
(
wr
.
Target
is
PhysicalBridge
bridge
)
bridge
.
ProcessBacklog
();
};
private
void
CheckBacklogForTimeouts
()
// check the head of the backlog queue, consuming anything that looks dead
...
...
src/StackExchange.Redis/PhysicalConnection.cs
View file @
ad0eb82c
...
...
@@ -52,7 +52,6 @@ private static readonly Message
private
int
failureReported
;
private
int
lastWriteTickCount
,
lastReadTickCount
,
lastBeatTickCount
;
private
int
firstUnansweredWriteTickCount
;
internal
void
GetBytes
(
out
long
sent
,
out
long
received
)
{
...
...
@@ -88,7 +87,6 @@ public PhysicalConnection(PhysicalBridge bridge)
internal
async
Task
BeginConnectAsync
(
TextWriter
log
)
{
Thread
.
VolatileWrite
(
ref
firstUnansweredWriteTickCount
,
0
);
var
bridge
=
BridgeCouldBeNull
;
var
endpoint
=
bridge
?.
ServerEndPoint
?.
EndPoint
;
if
(
endpoint
==
null
)
...
...
@@ -324,7 +322,17 @@ public Task FlushAsync()
{
int
now
=
Environment
.
TickCount
,
lastRead
=
Thread
.
VolatileRead
(
ref
lastReadTickCount
),
lastWrite
=
Thread
.
VolatileRead
(
ref
lastWriteTickCount
),
lastBeat
=
Thread
.
VolatileRead
(
ref
lastBeatTickCount
);
int
unansweredRead
=
Thread
.
VolatileRead
(
ref
firstUnansweredWriteTickCount
);
int
unansweredWriteTime
=
0
;
lock
(
_writtenAwaitingResponse
)
{
// find oldest message awaiting a response
if
(
_writtenAwaitingResponse
.
Count
!=
0
)
{
var
next
=
_writtenAwaitingResponse
.
Peek
();
unansweredWriteTime
=
next
.
GetWriteTime
();
}
}
var
exMessage
=
new
StringBuilder
(
failureType
.
ToString
());
...
...
@@ -371,7 +379,7 @@ void add(string lk, string sk, string v)
add
(
"Outstanding-Responses"
,
"outstanding"
,
GetSentAwaitingResponseCount
().
ToString
());
add
(
"Last-Read"
,
"last-read"
,
(
unchecked
(
now
-
lastRead
)
/
1000
)
+
"s ago"
);
add
(
"Last-Write"
,
"last-write"
,
(
unchecked
(
now
-
lastWrite
)
/
1000
)
+
"s ago"
);
add
(
"Unanswered-Write"
,
"unanswered-write"
,
(
unchecked
(
now
-
unansweredRead
)
/
1000
)
+
"s ago"
);
if
(
unansweredWriteTime
!=
0
)
add
(
"Unanswered-Write"
,
"unanswered-write"
,
(
unchecked
(
now
-
unansweredWriteTime
)
/
1000
)
+
"s ago"
);
add
(
"Keep-Alive"
,
"keep-alive"
,
bridge
.
ServerEndPoint
?.
WriteEverySeconds
+
"s"
);
add
(
"Previous-Physical-State"
,
"state"
,
oldState
.
ToString
());
add
(
"Manager"
,
"mgr"
,
bridge
.
Multiplexer
.
SocketManager
?.
GetState
());
...
...
@@ -696,9 +704,6 @@ internal void WriteHeader(RedisCommand command, int arguments, CommandBytes comm
// ExecuteMessage should have dealt with everything else
if
(
commandBytes
.
IsEmpty
)
throw
ExceptionFactory
.
CommandDisabled
(
command
);
// remember the time of the first write that still not followed by read
Interlocked
.
CompareExchange
(
ref
firstUnansweredWriteTickCount
,
Environment
.
TickCount
,
0
);
// *{argCount}\r\n = 3 + MaxInt32TextLen
// ${cmd-len}\r\n = 3 + MaxInt32TextLen
// {cmd}\r\n = 2 + commandBytes.Length
...
...
src/StackExchange.Redis/RawResult.cs
View file @
ad0eb82c
...
...
@@ -291,7 +291,7 @@ internal bool GetBoolean()
return
AsGeoPosition
(
root
.
GetItems
());
}
static
GeoPosition
AsGeoPosition
(
Sequence
<
RawResult
>
coords
)
private
static
GeoPosition
AsGeoPosition
(
in
Sequence
<
RawResult
>
coords
)
{
double
longitude
,
latitude
;
if
(
coords
.
IsSingleSegment
)
...
...
src/StackExchange.Redis/RedisSubscriber.cs
View file @
ad0eb82c
...
...
@@ -17,7 +17,7 @@ internal static void CompleteAsWorker(ICompletable completable)
if
(
completable
!=
null
)
ThreadPool
.
QueueUserWorkItem
(
s_CompleteAsWorker
,
completable
);
}
static
readonly
WaitCallback
s_CompleteAsWorker
=
s
=>
((
ICompletable
)
s
).
TryComplete
(
true
);
private
static
readonly
WaitCallback
s_CompleteAsWorker
=
s
=>
((
ICompletable
)
s
).
TryComplete
(
true
);
internal
static
bool
TryCompleteHandler
<
T
>(
EventHandler
<
T
>
handler
,
object
sender
,
T
args
,
bool
isAsync
)
where
T
:
EventArgs
,
ICompletable
{
...
...
@@ -261,7 +261,6 @@ public static PendingSubscriptionState Create(RedisChannel channel, Subscription
private
PendingSubscriptionState
(
object
asyncState
,
RedisChannel
channel
,
Subscription
subscription
,
CommandFlags
flags
,
bool
subscribe
,
bool
internalCall
,
bool
isSlave
)
{
var
cmd
=
subscribe
?
(
channel
.
IsPatternBased
?
RedisCommand
.
PSUBSCRIBE
:
RedisCommand
.
SUBSCRIBE
)
:
(
channel
.
IsPatternBased
?
RedisCommand
.
PUNSUBSCRIBE
:
RedisCommand
.
UNSUBSCRIBE
);
...
...
src/StackExchange.Redis/ResultProcessor.cs
View file @
ad0eb82c
...
...
@@ -1114,7 +1114,7 @@ public RedisChannelArrayProcessor(RedisChannel.PatternMode mode)
this
.
mode
=
mode
;
}
readonly
struct
ChannelState
// I would use a value-tuple here, but that is binding hell
private
readonly
struct
ChannelState
// I would use a value-tuple here, but that is binding hell
{
public
readonly
byte
[]
Prefix
;
public
readonly
RedisChannel
.
PatternMode
Mode
;
...
...
src/StackExchange.Redis/ServerSelectionStrategy.cs
View file @
ad0eb82c
...
...
@@ -8,7 +8,9 @@ internal sealed class ServerSelectionStrategy
{
public
const
int
NoSlot
=
-
1
,
MultipleSlots
=
-
2
;
private
const
int
RedisClusterSlotCount
=
16384
;
#pragma warning disable IDE1006 // Naming Styles
private
static
ReadOnlySpan
<
ushort
>
s_crc16tab
=>
new
ushort
[]
#pragma warning restore IDE1006 // Naming Styles
{
// this syntax allows a special-case population implementation by the compiler/JIT
0x0000
,
0x1021
,
0x2042
,
0x3063
,
0x4084
,
0x50a5
,
0x60c6
,
0x70e7
,
0x8108
,
0x9129
,
0xa14a
,
0xb16b
,
0xc18c
,
0xd1ad
,
0xe1ce
,
0xf1ef
,
...
...
@@ -72,6 +74,7 @@ private static unsafe int GetClusterSlot(in RedisKey key)
{
var
blob
=
(
byte
[])
key
;
fixed
(
byte
*
ptr
=
blob
)
{
fixed
(
ushort
*
crc16tab
=
s_crc16tab
)
{
int
offset
=
0
,
count
=
blob
.
Length
,
start
,
end
;
...
...
@@ -90,6 +93,7 @@ private static unsafe int GetClusterSlot(in RedisKey key)
}
}
}
}
public
ServerEndPoint
Select
(
Message
message
)
{
...
...
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