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
Show whitespace changes
Inline
Side-by-side
redis.conf
View file @
eeffcf38
...
@@ -292,6 +292,13 @@ appendfsync everysec
...
@@ -292,6 +292,13 @@ appendfsync everysec
# "no" that is the safest pick from the point of view of durability.
# "no" that is the safest pick from the point of view of durability.
no
-
appendfsync
-
on
-
rewrite
no
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 ###############################
#################################### DISK STORE ###############################
# When disk store is active Redis works as an on-disk database, where memory
# 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) {
...
@@ -296,6 +296,8 @@ void loadServerConfig(char *filename) {
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"cluster-config-file"
)
&&
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"cluster-config-file"
)
&&
argc
==
2
)
{
zfree
(
server
.
cluster
.
configfile
);
zfree
(
server
.
cluster
.
configfile
);
server
.
cluster
.
configfile
=
zstrdup
(
argv
[
1
]);
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
{
}
else
{
err
=
"Bad directive or wrong number of arguments"
;
goto
loaderr
;
err
=
"Bad directive or wrong number of arguments"
;
goto
loaderr
;
}
}
...
@@ -460,6 +462,9 @@ void configSetCommand(redisClient *c) {
...
@@ -460,6 +462,9 @@ void configSetCommand(redisClient *c) {
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"zset-max-ziplist-value"
))
{
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"zset-max-ziplist-value"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
zset_max_ziplist_value
=
ll
;
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
{
}
else
{
addReplyErrorFormat
(
c
,
"Unsupported CONFIG parameter: %s"
,
addReplyErrorFormat
(
c
,
"Unsupported CONFIG parameter: %s"
,
(
char
*
)
c
->
argv
[
2
]
->
ptr
);
(
char
*
)
c
->
argv
[
2
]
->
ptr
);
...
@@ -621,6 +626,11 @@ void configGetCommand(redisClient *c) {
...
@@ -621,6 +626,11 @@ void configGetCommand(redisClient *c) {
addReplyBulkLongLong
(
c
,
server
.
zset_max_ziplist_value
);
addReplyBulkLongLong
(
c
,
server
.
zset_max_ziplist_value
);
matches
++
;
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
);
setDeferredMultiBulkLength
(
c
,
replylen
,
matches
*
2
);
}
}
...
...
src/redis.c
View file @
eeffcf38
...
@@ -858,6 +858,7 @@ void initServerConfig() {
...
@@ -858,6 +858,7 @@ void initServerConfig() {
server
.
cache_flush_delay
=
0
;
server
.
cache_flush_delay
=
0
;
server
.
cluster_enabled
=
0
;
server
.
cluster_enabled
=
0
;
server
.
cluster
.
configfile
=
zstrdup
(
"nodes.conf"
);
server
.
cluster
.
configfile
=
zstrdup
(
"nodes.conf"
);
server
.
lua_time_limit
=
REDIS_LUA_TIME_LIMIT
;
updateLRUClock
();
updateLRUClock
();
resetServerSaveParams
();
resetServerSaveParams
();
...
...
src/redis.h
View file @
eeffcf38
...
@@ -225,6 +225,9 @@
...
@@ -225,6 +225,9 @@
#define REDIS_BGSAVE_THREAD_DONE_OK 2
#define REDIS_BGSAVE_THREAD_DONE_OK 2
#define REDIS_BGSAVE_THREAD_DONE_ERR 3
#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: */
/* 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 redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
...
@@ -659,6 +662,8 @@ struct redisServer {
...
@@ -659,6 +662,8 @@ struct redisServer {
/* Scripting */
/* Scripting */
lua_State
*
lua
;
lua_State
*
lua
;
redisClient
*
lua_client
;
redisClient
*
lua_client
;
long
long
lua_time_limit
;
long
long
lua_time_start
;
};
};
typedef
struct
pubsubPattern
{
typedef
struct
pubsubPattern
{
...
...
src/scripting.c
View file @
eeffcf38
...
@@ -199,6 +199,19 @@ int luaRedisCommand(lua_State *lua) {
...
@@ -199,6 +199,19 @@ int luaRedisCommand(lua_State *lua) {
return
1
;
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
)
{
void
scriptingInit
(
void
)
{
lua_State
*
lua
=
lua_open
();
lua_State
*
lua
=
lua_open
();
luaL_openlibs
(
lua
);
luaL_openlibs
(
lua
);
...
@@ -212,6 +225,10 @@ void scriptingInit(void) {
...
@@ -212,6 +225,10 @@ void scriptingInit(void) {
server
.
lua_client
=
createClient
(
-
1
);
server
.
lua_client
=
createClient
(
-
1
);
server
.
lua_client
->
flags
|=
REDIS_LUA_CLIENT
;
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
;
server
.
lua
=
lua
;
}
}
...
@@ -375,6 +392,7 @@ void evalCommand(redisClient *c) {
...
@@ -375,6 +392,7 @@ void evalCommand(redisClient *c) {
/* At this point whatever this script was never seen before or if it was
/* 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
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
* a single return value. */
server
.
lua_time_start
=
ustime
()
/
1000
;
if
(
lua_pcall
(
lua
,
0
,
1
,
0
))
{
if
(
lua_pcall
(
lua
,
0
,
1
,
0
))
{
selectDb
(
c
,
server
.
lua_client
->
db
->
id
);
/* set DB ID from Lua client */
selectDb
(
c
,
server
.
lua_client
->
db
->
id
);
/* set DB ID from Lua client */
addReplyErrorFormat
(
c
,
"Error running script (call to %s): %s
\n
"
,
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