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
b854e4d7
Commit
b854e4d7
authored
Mar 11, 2018
by
Nick Craver
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup: RedisTransaction
parent
4b03e8d2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
59 deletions
+50
-59
RedisTransaction.cs
StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs
+50
-59
No files found.
StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs
View file @
b854e4d7
...
...
@@ -46,15 +46,13 @@ public void Execute()
public
bool
Execute
(
CommandFlags
flags
)
{
ResultProcessor
<
bool
>
proc
;
var
msg
=
CreateMessage
(
flags
,
out
proc
);
var
msg
=
CreateMessage
(
flags
,
out
ResultProcessor
<
bool
>
proc
);
return
base
.
ExecuteSync
(
msg
,
proc
);
// need base to avoid our local "not supported" override
}
public
Task
<
bool
>
ExecuteAsync
(
CommandFlags
flags
)
{
ResultProcessor
<
bool
>
proc
;
var
msg
=
CreateMessage
(
flags
,
out
proc
);
var
msg
=
CreateMessage
(
flags
,
out
ResultProcessor
<
bool
>
proc
);
return
base
.
ExecuteAsync
(
msg
,
proc
);
// need base to avoid our local wrapping override
}
...
...
@@ -87,8 +85,7 @@ internal override Task<T> ExecuteAsync<T>(Message message, ResultProcessor<T> pr
// (there is no task for the inner command)
(
pending
??
(
pending
=
new
List
<
QueuedMessage
>())).
Add
(
queued
);
switch
(
message
.
Command
)
switch
(
message
.
Command
)
{
case
RedisCommand
.
UNKNOWN
:
case
RedisCommand
.
EVAL
:
...
...
@@ -110,6 +107,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor
{
throw
new
NotSupportedException
(
"ExecuteSync cannot be used inside a transaction"
);
}
private
Message
CreateMessage
(
CommandFlags
flags
,
out
ResultProcessor
<
bool
>
processor
)
{
var
work
=
pending
;
...
...
@@ -123,94 +121,91 @@ private Message CreateMessage(CommandFlags flags, out ResultProcessor<bool> proc
{
processor
=
null
;
return
null
;
// they won't notice if we don't do anything...
}
}
processor
=
ResultProcessor
.
DemandPONG
;
return
Message
.
Create
(-
1
,
flags
,
RedisCommand
.
PING
);
}
processor
=
TransactionProcessor
.
Default
;
return
new
TransactionMessage
(
Database
,
flags
,
cond
,
work
);
}
class
QueuedMessage
:
Message
private
class
QueuedMessage
:
Message
{
p
rivate
readonly
Message
wrapped
;
p
ublic
Message
Wrapped
{
get
;
}
private
volatile
bool
wasQueued
;
public
QueuedMessage
(
Message
message
)
:
base
(
message
.
Db
,
message
.
Flags
|
CommandFlags
.
NoRedirect
,
message
.
Command
)
{
message
.
SetNoRedirect
();
this
.
w
rapped
=
message
;
W
rapped
=
message
;
}
public
bool
WasQueued
{
get
{
return
wasQueued
;
}
set
{
wasQueued
=
value
;
}
get
=>
wasQueued
;
set
=>
wasQueued
=
value
;
}
public
Message
Wrapped
=>
wrapped
;
internal
override
void
WriteImpl
(
PhysicalConnection
physical
)
{
w
rapped
.
WriteImpl
(
physical
);
w
rapped
.
SetRequestSent
();
W
rapped
.
WriteImpl
(
physical
);
W
rapped
.
SetRequestSent
();
}
}
class
QueuedProcessor
:
ResultProcessor
<
bool
>
private
class
QueuedProcessor
:
ResultProcessor
<
bool
>
{
public
static
readonly
ResultProcessor
<
bool
>
Default
=
new
QueuedProcessor
();
static
readonly
byte
[]
QUEUED
=
Encoding
.
UTF8
.
GetBytes
(
"QUEUED"
);
private
static
readonly
byte
[]
QUEUED
=
Encoding
.
UTF8
.
GetBytes
(
"QUEUED"
);
protected
override
bool
SetResultCore
(
PhysicalConnection
connection
,
Message
message
,
RawResult
result
)
{
if
(
result
.
Type
==
ResultType
.
SimpleString
&&
result
.
IsEqual
(
QUEUED
))
if
(
result
.
Type
==
ResultType
.
SimpleString
&&
result
.
IsEqual
(
QUEUED
))
{
var
q
=
message
as
QueuedMessage
;
if
(
q
!=
null
)
q
.
WasQueued
=
true
;
if
(
message
is
QueuedMessage
q
)
{
q
.
WasQueued
=
true
;
}
return
true
;
}
return
false
;
}
}
class
TransactionMessage
:
Message
,
IMultiMessage
private
class
TransactionMessage
:
Message
,
IMultiMessage
{
static
readonly
ConditionResult
[]
NixConditions
=
new
ConditionResult
[
0
];
static
readonly
QueuedMessage
[]
NixMessages
=
new
QueuedMessage
[
0
];
private
ConditionResult
[]
conditions
;
private
QueuedMessage
[]
operations
;
private
static
readonly
ConditionResult
[]
NixConditions
=
new
ConditionResult
[
0
];
private
static
readonly
QueuedMessage
[]
NixMessages
=
new
QueuedMessage
[
0
];
private
readonly
ConditionResult
[]
conditions
;
public
QueuedMessage
[]
InnerOperations
{
get
;
}
public
TransactionMessage
(
int
db
,
CommandFlags
flags
,
List
<
ConditionResult
>
conditions
,
List
<
QueuedMessage
>
operations
)
:
base
(
db
,
flags
,
RedisCommand
.
EXEC
)
{
this
.
o
perations
=
(
operations
==
null
||
operations
.
Count
==
0
)
?
NixMessages
:
operations
.
ToArray
();
this
.
InnerO
perations
=
(
operations
==
null
||
operations
.
Count
==
0
)
?
NixMessages
:
operations
.
ToArray
();
this
.
conditions
=
(
conditions
==
null
||
conditions
.
Count
==
0
)
?
NixConditions
:
conditions
.
ToArray
();
}
public
QueuedMessage
[]
InnerOperations
=>
operations
;
public
bool
IsAborted
=>
command
!=
RedisCommand
.
EXEC
;
public
override
void
AppendStormLog
(
StringBuilder
sb
)
{
base
.
AppendStormLog
(
sb
);
if
(
conditions
.
Length
!=
0
)
sb
.
Append
(
", "
).
Append
(
conditions
.
Length
).
Append
(
" conditions"
);
sb
.
Append
(
", "
).
Append
(
o
perations
.
Length
).
Append
(
" operations"
);
sb
.
Append
(
", "
).
Append
(
InnerO
perations
.
Length
).
Append
(
" operations"
);
}
public
override
int
GetHashSlot
(
ServerSelectionStrategy
serverSelectionStrategy
)
{
int
slot
=
ServerSelectionStrategy
.
NoSlot
;
for
(
int
i
=
0
;
i
<
conditions
.
Length
;
i
++)
for
(
int
i
=
0
;
i
<
conditions
.
Length
;
i
++)
{
int
newSlot
=
conditions
[
i
].
Condition
.
GetHashSlot
(
serverSelectionStrategy
);
slot
=
serverSelectionStrategy
.
CombineSlot
(
slot
,
newSlot
);
if
(
slot
==
ServerSelectionStrategy
.
MultipleSlots
)
return
slot
;
}
for
(
int
i
=
0
;
i
<
operations
.
Length
;
i
++)
for
(
int
i
=
0
;
i
<
InnerOperations
.
Length
;
i
++)
{
int
newSlot
=
o
perations
[
i
].
Wrapped
.
GetHashSlot
(
serverSelectionStrategy
);
int
newSlot
=
InnerO
perations
[
i
].
Wrapped
.
GetHashSlot
(
serverSelectionStrategy
);
slot
=
serverSelectionStrategy
.
CombineSlot
(
slot
,
newSlot
);
if
(
slot
==
ServerSelectionStrategy
.
MultipleSlots
)
return
slot
;
}
...
...
@@ -279,11 +274,11 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
// PART 3: issue the commands
if
(!
IsAborted
&&
o
perations
.
Length
!=
0
)
if
(!
IsAborted
&&
InnerO
perations
.
Length
!=
0
)
{
multiplexer
.
Trace
(
"Issuing transaction operations"
);
foreach
(
var
op
in
o
perations
)
foreach
(
var
op
in
InnerO
perations
)
{
if
(
explicitCheckForQueued
)
{
// need to have locked them before sending them
...
...
@@ -311,7 +306,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
else
{
foreach
(
var
op
in
o
perations
)
foreach
(
var
op
in
InnerO
perations
)
{
if
(!
op
.
WasQueued
)
{
...
...
@@ -321,7 +316,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
}
}
multiplexer
.
Trace
(
"Confirmed: QUEUED x "
+
o
perations
.
Length
);
multiplexer
.
Trace
(
"Confirmed: QUEUED x "
+
InnerO
perations
.
Length
);
}
else
{
...
...
@@ -341,7 +336,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{
connection
.
Multiplexer
.
Trace
(
"Aborting: canceling wrapped messages"
);
var
bridge
=
connection
.
Bridge
;
foreach
(
var
op
in
o
perations
)
foreach
(
var
op
in
InnerO
perations
)
{
op
.
Wrapped
.
Cancel
();
bridge
.
CompleteSyncOrAsync
(
op
.
Wrapped
);
...
...
@@ -376,32 +371,28 @@ private bool AreAllConditionsSatisfied(ConnectionMultiplexer multiplexer)
}
}
class
TransactionProcessor
:
ResultProcessor
<
bool
>
private
class
TransactionProcessor
:
ResultProcessor
<
bool
>
{
public
static
readonly
TransactionProcessor
Default
=
new
TransactionProcessor
();
public
static
readonly
TransactionProcessor
Default
=
new
TransactionProcessor
();
public
override
bool
SetResult
(
PhysicalConnection
connection
,
Message
message
,
RawResult
result
)
{
if
(
result
.
IsError
)
{
var
tran
=
message
as
TransactionMessage
;
if
(
tran
!=
null
)
{
string
error
=
result
.
GetString
();
var
bridge
=
connection
.
Bridge
;
foreach
(
var
op
in
tran
.
InnerOperations
)
{
ServerFail
(
op
.
Wrapped
,
error
);
bridge
.
CompleteSyncOrAsync
(
op
.
Wrapped
);
}
if
(
result
.
IsError
&&
message
is
TransactionMessage
tran
)
{
string
error
=
result
.
GetString
();
var
bridge
=
connection
.
Bridge
;
foreach
(
var
op
in
tran
.
InnerOperations
)
{
ServerFail
(
op
.
Wrapped
,
error
);
bridge
.
CompleteSyncOrAsync
(
op
.
Wrapped
);
}
}
return
base
.
SetResult
(
connection
,
message
,
result
);
}
protected
override
bool
SetResultCore
(
PhysicalConnection
connection
,
Message
message
,
RawResult
result
)
{
var
tran
=
message
as
TransactionMessage
;
if
(
tran
!=
null
)
if
(
message
is
TransactionMessage
tran
)
{
var
bridge
=
connection
.
Bridge
;
var
wrapped
=
tran
.
InnerOperations
;
...
...
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