Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
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
...
@@ -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