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
c5034d50
Commit
c5034d50
authored
Mar 11, 2018
by
Nick Craver
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup: LuaScript
parent
78dc930d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
39 additions
and
42 deletions
+39
-42
LuaScript.cs
StackExchange.Redis/StackExchange/Redis/LuaScript.cs
+39
-42
No files found.
StackExchange.Redis/StackExchange/Redis/LuaScript.cs
View file @
c5034d50
...
@@ -20,26 +20,26 @@ public sealed class LuaScript
...
@@ -20,26 +20,26 @@ public sealed class LuaScript
{
{
// Since the mapping of "script text" -> LuaScript doesn't depend on any particular details of
// Since the mapping of "script text" -> LuaScript doesn't depend on any particular details of
// the redis connection itself, this cache is global.
// the redis connection itself, this cache is global.
static
readonly
ConcurrentDictionary
<
string
,
WeakReference
>
Cache
=
new
ConcurrentDictionary
<
string
,
WeakReference
>();
private
static
readonly
ConcurrentDictionary
<
string
,
WeakReference
>
Cache
=
new
ConcurrentDictionary
<
string
,
WeakReference
>();
/// <summary>
/// <summary>
/// The original Lua script that was used to create this.
/// The original Lua script that was used to create this.
/// </summary>
/// </summary>
public
string
OriginalScript
{
get
;
private
set
;
}
public
string
OriginalScript
{
get
;
}
/// <summary>
/// <summary>
/// The Lua script that will actually be sent to Redis for execution.
/// The Lua script that will actually be sent to Redis for execution.
///
///
/// All @-prefixed parameter names have been replaced at this point.
/// All @-prefixed parameter names have been replaced at this point.
/// </summary>
/// </summary>
public
string
ExecutableScript
{
get
;
private
set
;
}
public
string
ExecutableScript
{
get
;
}
// Arguments are in the order they have to passed to the script in
// Arguments are in the order they have to passed to the script in
internal
string
[]
Arguments
{
get
;
private
set
;
}
internal
string
[]
Arguments
{
get
;
}
bool
HasArguments
=>
Arguments
!=
null
&&
Arguments
.
Length
>
0
;
private
bool
HasArguments
=>
Arguments
?
.
Length
>
0
;
Hashtable
ParameterMappers
;
private
readonly
Hashtable
ParameterMappers
;
internal
LuaScript
(
string
originalScript
,
string
executableScript
,
string
[]
arguments
)
internal
LuaScript
(
string
originalScript
,
string
executableScript
,
string
[]
arguments
)
{
{
...
@@ -61,8 +61,7 @@ internal LuaScript(string originalScript, string executableScript, string[] argu
...
@@ -61,8 +61,7 @@ internal LuaScript(string originalScript, string executableScript, string[] argu
{
{
try
try
{
{
WeakReference
ignored
;
Cache
.
TryRemove
(
OriginalScript
,
out
_
);
Cache
.
TryRemove
(
OriginalScript
,
out
ignored
);
}
}
catch
{
}
catch
{
}
}
}
...
@@ -72,28 +71,22 @@ internal LuaScript(string originalScript, string executableScript, string[] argu
...
@@ -72,28 +71,22 @@ internal LuaScript(string originalScript, string executableScript, string[] argu
/// Existing LuaScripts will continue to work, but future calls to LuaScript.Prepare
/// Existing LuaScripts will continue to work, but future calls to LuaScript.Prepare
/// return a new LuaScript instance.
/// return a new LuaScript instance.
/// </summary>
/// </summary>
public
static
void
PurgeCache
()
public
static
void
PurgeCache
()
=>
Cache
.
Clear
();
{
Cache
.
Clear
();
}
/// <summary>
/// <summary>
/// Returns the number of cached LuaScripts.
/// Returns the number of cached LuaScripts.
/// </summary>
/// </summary>
public
static
int
GetCachedScriptCount
()
public
static
int
GetCachedScriptCount
()
=>
Cache
.
Count
;
{
return
Cache
.
Count
;
}
/// <summary>
/// <summary>
/// Prepares a Lua script with named parameters to be run against any Redis instance.
/// Prepares a Lua script with named parameters to be run against any Redis instance.
/// </summary>
/// </summary>
/// <param name="script">The script to prepare.</param>
public
static
LuaScript
Prepare
(
string
script
)
public
static
LuaScript
Prepare
(
string
script
)
{
{
LuaScript
ret
;
LuaScript
ret
;
WeakReference
weakRef
;
if
(!
Cache
.
TryGetValue
(
script
,
out
WeakReference
weakRef
)
||
(
ret
=
(
LuaScript
)
weakRef
.
Target
)
==
null
)
if
(!
Cache
.
TryGetValue
(
script
,
out
weakRef
)
||
(
ret
=
(
LuaScript
)
weakRef
.
Target
)
==
null
)
{
{
ret
=
ScriptParameterMapper
.
PrepareScript
(
script
);
ret
=
ScriptParameterMapper
.
PrepareScript
(
script
);
Cache
[
script
]
=
new
WeakReference
(
ret
);
Cache
[
script
]
=
new
WeakReference
(
ret
);
...
@@ -117,9 +110,7 @@ internal void ExtractParameters(object ps, RedisKey? keyPrefix, out RedisKey[] k
...
@@ -117,9 +110,7 @@ internal void ExtractParameters(object ps, RedisKey? keyPrefix, out RedisKey[] k
mapper
=
(
Func
<
object
,
RedisKey
?,
ScriptParameterMapper
.
ScriptParameters
>)
ParameterMappers
[
psType
];
mapper
=
(
Func
<
object
,
RedisKey
?,
ScriptParameterMapper
.
ScriptParameters
>)
ParameterMappers
[
psType
];
if
(
mapper
==
null
)
if
(
mapper
==
null
)
{
{
string
missingMember
;
if
(!
ScriptParameterMapper
.
IsValidParameterHash
(
psType
,
this
,
out
string
missingMember
,
out
string
badMemberType
))
string
badMemberType
;
if
(!
ScriptParameterMapper
.
IsValidParameterHash
(
psType
,
this
,
out
missingMember
,
out
badMemberType
))
{
{
if
(
missingMember
!=
null
)
if
(
missingMember
!=
null
)
{
{
...
@@ -148,24 +139,26 @@ internal void ExtractParameters(object ps, RedisKey? keyPrefix, out RedisKey[] k
...
@@ -148,24 +139,26 @@ internal void ExtractParameters(object ps, RedisKey? keyPrefix, out RedisKey[] k
/// <summary>
/// <summary>
/// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any.
/// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any.
/// </summary>
/// </summary>
/// <param name="db">The redis databse to evaluate against.</param>
/// <param name="ps">The parameter object to use.</param>
/// <param name="withKeyPrefix">The key prefix to use, if any.</param>
/// <param name="flags">The command flags to use.</param>
public
RedisResult
Evaluate
(
IDatabase
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
RedisResult
Evaluate
(
IDatabase
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
RedisKey
[]
keys
;
ExtractParameters
(
ps
,
withKeyPrefix
,
out
RedisKey
[]
keys
,
out
RedisValue
[]
args
);
RedisValue
[]
args
;
ExtractParameters
(
ps
,
withKeyPrefix
,
out
keys
,
out
args
);
return
db
.
ScriptEvaluate
(
ExecutableScript
,
keys
,
args
,
flags
);
return
db
.
ScriptEvaluate
(
ExecutableScript
,
keys
,
args
,
flags
);
}
}
/// <summary>
/// <summary>
/// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any.
/// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any.
/// </summary>
/// </summary>
/// <param name="db">The redis databse to evaluate against.</param>
/// <param name="ps">The parameter object to use.</param>
/// <param name="withKeyPrefix">The key prefix to use, if any.</param>
/// <param name="flags">The command flags to use.</param>
public
Task
<
RedisResult
>
EvaluateAsync
(
IDatabaseAsync
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
Task
<
RedisResult
>
EvaluateAsync
(
IDatabaseAsync
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
RedisKey
[]
keys
;
ExtractParameters
(
ps
,
withKeyPrefix
,
out
RedisKey
[]
keys
,
out
RedisValue
[]
args
);
RedisValue
[]
args
;
ExtractParameters
(
ps
,
withKeyPrefix
,
out
keys
,
out
args
);
return
db
.
ScriptEvaluateAsync
(
ExecutableScript
,
keys
,
args
,
flags
);
return
db
.
ScriptEvaluateAsync
(
ExecutableScript
,
keys
,
args
,
flags
);
}
}
...
@@ -175,15 +168,16 @@ public Task<RedisResult> EvaluateAsync(IDatabaseAsync db, object ps = null, Redi
...
@@ -175,15 +168,16 @@ public Task<RedisResult> EvaluateAsync(IDatabaseAsync db, object ps = null, Redi
///
///
/// Note: the FireAndForget command flag cannot be set
/// Note: the FireAndForget command flag cannot be set
/// </summary>
/// </summary>
/// <param name="server">The server to load the script on.</param>
/// <param name="flags">The command flags to use.</param>
public
LoadedLuaScript
Load
(
IServer
server
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
LoadedLuaScript
Load
(
IServer
server
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
if
(
flags
.
HasFlag
(
CommandFlags
.
FireAndForget
)
)
if
(
(
flags
&
CommandFlags
.
FireAndForget
)
!=
0
)
{
{
throw
new
ArgumentOutOfRangeException
(
nameof
(
flags
),
"Loading a script cannot be FireAndForget"
);
throw
new
ArgumentOutOfRangeException
(
nameof
(
flags
),
"Loading a script cannot be FireAndForget"
);
}
}
var
hash
=
server
.
ScriptLoad
(
ExecutableScript
,
flags
);
var
hash
=
server
.
ScriptLoad
(
ExecutableScript
,
flags
);
return
new
LoadedLuaScript
(
this
,
hash
);
return
new
LoadedLuaScript
(
this
,
hash
);
}
}
...
@@ -193,15 +187,16 @@ public LoadedLuaScript Load(IServer server, CommandFlags flags = CommandFlags.No
...
@@ -193,15 +187,16 @@ public LoadedLuaScript Load(IServer server, CommandFlags flags = CommandFlags.No
///
///
/// Note: the FireAndForget command flag cannot be set
/// Note: the FireAndForget command flag cannot be set
/// </summary>
/// </summary>
/// <param name="server">The server to load the script on.</param>
/// <param name="flags">The command flags to use.</param>
public
async
Task
<
LoadedLuaScript
>
LoadAsync
(
IServer
server
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
async
Task
<
LoadedLuaScript
>
LoadAsync
(
IServer
server
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
if
(
flags
.
HasFlag
(
CommandFlags
.
FireAndForget
)
)
if
(
(
flags
&
CommandFlags
.
FireAndForget
)
!=
0
)
{
{
throw
new
ArgumentOutOfRangeException
(
nameof
(
flags
),
"Loading a script cannot be FireAndForget"
);
throw
new
ArgumentOutOfRangeException
(
nameof
(
flags
),
"Loading a script cannot be FireAndForget"
);
}
}
var
hash
=
await
server
.
ScriptLoadAsync
(
ExecutableScript
,
flags
).
ForAwait
();
var
hash
=
await
server
.
ScriptLoadAsync
(
ExecutableScript
,
flags
).
ForAwait
();
return
new
LoadedLuaScript
(
this
,
hash
);
return
new
LoadedLuaScript
(
this
,
hash
);
}
}
}
}
...
@@ -240,7 +235,7 @@ public sealed class LoadedLuaScript
...
@@ -240,7 +235,7 @@ public sealed class LoadedLuaScript
///
///
/// This is sent to Redis instead of ExecutableScript during Evaluate and EvaluateAsync calls.
/// This is sent to Redis instead of ExecutableScript during Evaluate and EvaluateAsync calls.
/// </summary>
/// </summary>
public
byte
[]
Hash
{
get
;
private
set
;
}
public
byte
[]
Hash
{
get
;
}
// internal for testing purposes only
// internal for testing purposes only
internal
LuaScript
Original
;
internal
LuaScript
Original
;
...
@@ -257,12 +252,13 @@ internal LoadedLuaScript(LuaScript original, byte[] hash)
...
@@ -257,12 +252,13 @@ internal LoadedLuaScript(LuaScript original, byte[] hash)
/// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not
/// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not
/// been loaded into the passed Redis instance it will fail.
/// been loaded into the passed Redis instance it will fail.
/// </summary>
/// </summary>
/// <param name="db">The redis databse to evaluate against.</param>
/// <param name="ps">The parameter object to use.</param>
/// <param name="withKeyPrefix">The key prefix to use, if any.</param>
/// <param name="flags">The command flags to use.</param>
public
RedisResult
Evaluate
(
IDatabase
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
RedisResult
Evaluate
(
IDatabase
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
RedisKey
[]
keys
;
Original
.
ExtractParameters
(
ps
,
withKeyPrefix
,
out
RedisKey
[]
keys
,
out
RedisValue
[]
args
);
RedisValue
[]
args
;
Original
.
ExtractParameters
(
ps
,
withKeyPrefix
,
out
keys
,
out
args
);
return
db
.
ScriptEvaluate
(
Hash
,
keys
,
args
,
flags
);
return
db
.
ScriptEvaluate
(
Hash
,
keys
,
args
,
flags
);
}
}
...
@@ -272,12 +268,13 @@ public RedisResult Evaluate(IDatabase db, object ps = null, RedisKey? withKeyPre
...
@@ -272,12 +268,13 @@ public RedisResult Evaluate(IDatabase db, object ps = null, RedisKey? withKeyPre
/// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not
/// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not
/// been loaded into the passed Redis instance it will fail.
/// been loaded into the passed Redis instance it will fail.
/// </summary>
/// </summary>
/// <param name="db">The redis databse to evaluate against.</param>
/// <param name="ps">The parameter object to use.</param>
/// <param name="withKeyPrefix">The key prefix to use, if any.</param>
/// <param name="flags">The command flags to use.</param>
public
Task
<
RedisResult
>
EvaluateAsync
(
IDatabaseAsync
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
public
Task
<
RedisResult
>
EvaluateAsync
(
IDatabaseAsync
db
,
object
ps
=
null
,
RedisKey
?
withKeyPrefix
=
null
,
CommandFlags
flags
=
CommandFlags
.
None
)
{
{
RedisKey
[]
keys
;
Original
.
ExtractParameters
(
ps
,
withKeyPrefix
,
out
RedisKey
[]
keys
,
out
RedisValue
[]
args
);
RedisValue
[]
args
;
Original
.
ExtractParameters
(
ps
,
withKeyPrefix
,
out
keys
,
out
args
);
return
db
.
ScriptEvaluateAsync
(
Hash
,
keys
,
args
,
flags
);
return
db
.
ScriptEvaluateAsync
(
Hash
,
keys
,
args
,
flags
);
}
}
}
}
...
...
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