Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
eeffcf38
Commit
eeffcf38
authored
May 06, 2011
by
antirez
Browse files
Lua scripts max execution time
parent
8c3402df
Changes
5
Hide whitespace changes
Inline
Side-by-side
redis.conf
View file @
eeffcf38
...
...
@@ -292,6 +292,13 @@ appendfsync everysec
# "no" that is the safest pick from the point of view of durability.
no
-
appendfsync
-
on
-
rewrite
no
################################ LUA SCRIPTING ###############################
# Max execution time of a Lua script in milliseconds.
# This prevents that a programming error generating an infinite loop will block
# your server forever. Set it to 0 or a negative value for unlimited execution.
lua
-
time
-
limit
60000
#################################### DISK STORE ###############################
# When disk store is active Redis works as an on-disk database, where memory
...
...
src/config.c
View file @
eeffcf38
...
...
@@ -296,6 +296,8 @@ void loadServerConfig(char *filename) {
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"cluster-config-file"
)
&&
argc
==
2
)
{
zfree
(
server
.
cluster
.
configfile
);
server
.
cluster
.
configfile
=
zstrdup
(
argv
[
1
]);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"lua-time-limit"
)
&&
argc
==
2
)
{
server
.
lua_time_limit
=
strtoll
(
argv
[
1
],
NULL
,
10
);
}
else
{
err
=
"Bad directive or wrong number of arguments"
;
goto
loaderr
;
}
...
...
@@ -460,6 +462,9 @@ void configSetCommand(redisClient *c) {
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"zset-max-ziplist-value"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
zset_max_ziplist_value
=
ll
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"lua-time-limit"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
lua_time_limit
=
ll
;
}
else
{
addReplyErrorFormat
(
c
,
"Unsupported CONFIG parameter: %s"
,
(
char
*
)
c
->
argv
[
2
]
->
ptr
);
...
...
@@ -621,6 +626,11 @@ void configGetCommand(redisClient *c) {
addReplyBulkLongLong
(
c
,
server
.
zset_max_ziplist_value
);
matches
++
;
}
if
(
stringmatch
(
pattern
,
"lua-time-limit"
,
0
))
{
addReplyBulkCString
(
c
,
"lua-time-limit"
);
addReplyBulkLongLong
(
c
,
server
.
lua_time_limit
);
matches
++
;
}
setDeferredMultiBulkLength
(
c
,
replylen
,
matches
*
2
);
}
...
...
src/redis.c
View file @
eeffcf38
...
...
@@ -858,6 +858,7 @@ void initServerConfig() {
server
.
cache_flush_delay
=
0
;
server
.
cluster_enabled
=
0
;
server
.
cluster
.
configfile
=
zstrdup
(
"nodes.conf"
);
server
.
lua_time_limit
=
REDIS_LUA_TIME_LIMIT
;
updateLRUClock
();
resetServerSaveParams
();
...
...
src/redis.h
View file @
eeffcf38
...
...
@@ -225,6 +225,9 @@
#define REDIS_BGSAVE_THREAD_DONE_OK 2
#define REDIS_BGSAVE_THREAD_DONE_ERR 3
/* Scripting */
#define REDIS_LUA_TIME_LIMIT 60000
/* milliseconds */
/* We can print the stacktrace, so our assert is defined this way: */
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
...
...
@@ -659,6 +662,8 @@ struct redisServer {
/* Scripting */
lua_State
*
lua
;
redisClient
*
lua_client
;
long
long
lua_time_limit
;
long
long
lua_time_start
;
};
typedef
struct
pubsubPattern
{
...
...
src/scripting.c
View file @
eeffcf38
...
...
@@ -199,6 +199,19 @@ int luaRedisCommand(lua_State *lua) {
return
1
;
}
void
luaMaskCountHook
(
lua_State
*
lua
,
lua_Debug
*
ar
)
{
long
long
elapsed
;
REDIS_NOTUSED
(
ar
);
if
(
server
.
lua_time_limit
<=
0
)
return
;
elapsed
=
(
ustime
()
/
1000
)
-
server
.
lua_time_start
;
if
(
elapsed
>=
server
.
lua_time_limit
)
{
lua_pushstring
(
lua
,
"Script aborted for max execution time..."
);
lua_error
(
lua
);
redisLog
(
REDIS_NOTICE
,
"Lua script aborted for max execution time after %lld milliseconds of running time"
,
elapsed
);
}
}
void
scriptingInit
(
void
)
{
lua_State
*
lua
=
lua_open
();
luaL_openlibs
(
lua
);
...
...
@@ -212,6 +225,10 @@ void scriptingInit(void) {
server
.
lua_client
=
createClient
(
-
1
);
server
.
lua_client
->
flags
|=
REDIS_LUA_CLIENT
;
/* Set an hook in order to be able to stop the script execution if it
* is running for too much time. */
lua_sethook
(
lua
,
luaMaskCountHook
,
LUA_MASKCOUNT
,
10000
);
server
.
lua
=
lua
;
}
...
...
@@ -375,6 +392,7 @@ void evalCommand(redisClient *c) {
/* At this point whatever this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
server
.
lua_time_start
=
ustime
()
/
1000
;
if
(
lua_pcall
(
lua
,
0
,
1
,
0
))
{
selectDb
(
c
,
server
.
lua_client
->
db
->
id
);
/* set DB ID from Lua client */
addReplyErrorFormat
(
c
,
"Error running script (call to %s): %s
\n
"
,
...
...
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