Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
hanoi2005
redis
提交
99e01c7e
R
redis
项目概览
hanoi2005
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
99e01c7e
编写于
1月 29, 2014
作者:
J
Jonathan Pickett
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Sentinel working on Windows. Eliminated use of fork, instead relying on async CreateProcess.
上级
4440406b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
101 addition
and
7 deletion
+101
-7
deps/hiredis/sds.h
deps/hiredis/sds.h
+1
-1
src/sentinel.c
src/sentinel.c
+100
-6
未找到文件。
deps/hiredis/sds.h
浏览文件 @
99e01c7e
...
...
@@ -44,7 +44,7 @@ typedef char *sds;
struct
sdshdr
{
int
len
;
int
free
;
char
*
buf
;
char
buf
[]
;
};
static
inline
size_t
sdslen
(
const
sds
s
)
{
...
...
src/sentinel.c
浏览文件 @
99e01c7e
...
...
@@ -217,7 +217,12 @@ typedef struct sentinelScriptJob {
execution at any time. If the script is not
running and it's not 0, it means: do not run
before the specified time. */
#ifdef _WIN32
HANDLE
hScriptProcess
;
/* handle of process executing script */
pid_t
processId
;
/* Script execution pid. (for reporting only) */
#else
pid_t
pid
;
/* Script execution pid. */
#endif
}
sentinelScriptJob
;
/* ======================= hiredis ae.c adapters =============================
...
...
@@ -595,7 +600,12 @@ void sentinelScheduleScriptExecution(char *path, ...) {
sj
->
retry_num
=
0
;
sj
->
argv
=
zmalloc
(
sizeof
(
char
*
)
*
(
argc
+
1
));
sj
->
start_time
=
0
;
#ifdef _WIN32
sj
->
hScriptProcess
=
INVALID_HANDLE_VALUE
;
sj
->
processId
=
0
;
#else
sj
->
pid
=
0
;
#endif
memcpy
(
sj
->
argv
,
argv
,
sizeof
(
char
*
)
*
(
argc
+
1
));
listAddNodeTail
(
sentinel
.
scripts_queue
,
sj
);
...
...
@@ -622,6 +632,7 @@ void sentinelScheduleScriptExecution(char *path, ...) {
/* Lookup a script in the scripts queue via pid, and returns the list node
* (so that we can easily remove it from the queue if needed). */
#ifndef _WIN32
listNode
*
sentinelGetScriptListNodeByPid
(
pid_t
pid
)
{
listNode
*
ln
;
listIter
li
;
...
...
@@ -635,6 +646,7 @@ listNode *sentinelGetScriptListNodeByPid(pid_t pid) {
}
return
NULL
;
}
#endif
/* Run pending scripts if we are not already at max number of running
* scripts. */
...
...
@@ -647,8 +659,7 @@ void sentinelRunPendingScripts(void) {
* tail of the queue, so we run older jobs first. */
listRewind
(
sentinel
.
scripts_queue
,
&
li
);
while
(
sentinel
.
running_scripts
<
SENTINEL_SCRIPT_MAX_RUNNING
&&
(
ln
=
listNext
(
&
li
))
!=
NULL
)
{
(
ln
=
listNext
(
&
li
))
!=
NULL
)
{
sentinelScriptJob
*
sj
=
ln
->
value
;
pid_t
pid
;
...
...
@@ -661,6 +672,38 @@ void sentinelRunPendingScripts(void) {
sj
->
flags
|=
SENTINEL_SCRIPT_RUNNING
;
sj
->
start_time
=
mstime
();
sj
->
retry_num
++
;
#ifdef _WIN32
{
PROCESS_INFORMATION
pi
;
char
args
[
1024
];
int
j
=
1
;
int
pos
=
0
;
while
(
sj
->
argv
[
j
])
{
int
arglen
=
strlen
(
sj
->
argv
[
j
]);
memcpy
(
args
+
pos
,
sj
->
argv
[
j
],
arglen
);
pos
+=
arglen
;
memcpy
(
args
+
pos
,
" "
,
1
);
pos
+=
1
;
j
++
;
}
if
(
TRUE
==
CreateProcessA
(
sj
->
argv
[
0
],
args
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
NULL
,
&
pi
))
{
sj
->
hScriptProcess
=
pi
.
hProcess
;
sj
->
processId
=
pi
.
dwProcessId
;
CloseHandle
(
pi
.
hThread
);
sentinel
.
running_scripts
++
;
sentinelEvent
(
REDIS_DEBUG
,
"+script-child"
,
NULL
,
"%ld"
,(
long
)
sj
->
processId
);
}
else
{
sentinelEvent
(
REDIS_WARNING
,
"-script-error"
,
NULL
,
"%s %d %d"
,
sj
->
argv
[
0
],
99
,
0
);
sj
->
flags
&=
~
SENTINEL_SCRIPT_RUNNING
;
sj
->
processId
=
0
;
sj
->
hScriptProcess
=
INVALID_HANDLE_VALUE
;
}
}
}
#else
pid
=
fork
();
if
(
pid
==
-
1
)
{
...
...
@@ -673,11 +716,7 @@ void sentinelRunPendingScripts(void) {
sj
->
pid
=
0
;
}
else
if
(
pid
==
0
)
{
/* Child */
#ifdef _WIN32
_execv
(
sj
->
argv
[
0
],
sj
->
argv
);
#else
execve
(
sj
->
argv
[
0
],
sj
->
argv
,
environ
);
#endif
/* If we are here an error occurred. */
_exit
(
2
);
/* Don't retry execution. */
}
else
{
...
...
@@ -686,6 +725,7 @@ void sentinelRunPendingScripts(void) {
sentinelEvent
(
REDIS_DEBUG
,
"+script-child"
,
NULL
,
"%ld"
,(
long
)
pid
);
}
}
#endif
}
/* How much to delay the execution of a script that we need to retry after
...
...
@@ -707,6 +747,49 @@ mstime_t sentinelScriptRetryDelay(int retry_num) {
* a signal, or returned exit code "1", it is scheduled to run again if
* the max number of retries did not already elapsed. */
void
sentinelCollectTerminatedScripts
(
void
)
{
#ifdef _WIN32
listNode
*
ln
;
listIter
li
;
DWORD
exitCode
;
listRewind
(
sentinel
.
scripts_queue
,
&
li
);
while
(
sentinel
.
running_scripts
<
SENTINEL_SCRIPT_MAX_RUNNING
&&
(
ln
=
listNext
(
&
li
))
!=
NULL
)
{
sentinelScriptJob
*
sj
=
ln
->
value
;
if
(
sj
->
hScriptProcess
==
INVALID_HANDLE_VALUE
)
continue
;
if
(
WaitForSingleObject
(
sj
->
hScriptProcess
,
0
)
==
WAIT_OBJECT_0
)
{
GetExitCodeProcess
(
sj
->
hScriptProcess
,
&
exitCode
);
sentinelEvent
(
REDIS_DEBUG
,
"-script-child"
,
NULL
,
"%ld %d %d"
,
(
long
)
sj
->
processId
,
exitCode
,
0
);
/* at this point the process ID may be recycled by Windows */
CloseHandle
(
sj
->
hScriptProcess
);
/* If the script returns an exit code of "1" (that means: please retry),
* we reschedule it if the max number of retries is not already reached. */
if
(
exitCode
==
1
&&
sj
->
retry_num
!=
SENTINEL_SCRIPT_MAX_RETRY
)
{
sj
->
hScriptProcess
=
INVALID_HANDLE_VALUE
;
sj
->
processId
=
0
;
sj
->
flags
&=
~
SENTINEL_SCRIPT_RUNNING
;
sj
->
start_time
=
mstime
()
+
sentinelScriptRetryDelay
(
sj
->
retry_num
);
}
else
{
/* Otherwise let's remove the script, but log the event if the
* execution did not terminated in the best of the ways. */
if
(
exitCode
!=
0
)
{
sentinelEvent
(
REDIS_WARNING
,
"-script-error"
,
NULL
,
"%s %d"
,
sj
->
argv
[
0
],
exitCode
);
}
listDelNode
(
sentinel
.
scripts_queue
,
ln
);
sentinelReleaseScriptJob
(
sj
);
sentinel
.
running_scripts
--
;
}
}
}
#else
int
statloc
;
pid_t
pid
;
...
...
@@ -749,6 +832,7 @@ void sentinelCollectTerminatedScripts(void) {
sentinel
.
running_scripts
--
;
}
}
#endif
}
/* Kill scripts in timeout, they'll be collected by the
...
...
@@ -765,9 +849,15 @@ void sentinelKillTimedoutScripts(void) {
if
(
sj
->
flags
&
SENTINEL_SCRIPT_RUNNING
&&
(
now
-
sj
->
start_time
)
>
SENTINEL_SCRIPT_MAX_RUNTIME
)
{
#ifdef _WIN32
sentinelEvent
(
REDIS_WARNING
,
"-script-timeout"
,
NULL
,
"%s %ld"
,
sj
->
argv
[
0
],
(
long
)
sj
->
processId
);
TerminateProcess
(
sj
->
hScriptProcess
,
1
);
#else
sentinelEvent
(
REDIS_WARNING
,
"-script-timeout"
,
NULL
,
"%s %ld"
,
sj
->
argv
[
0
],
(
long
)
sj
->
pid
);
kill
(
sj
->
pid
,
SIGKILL
);
#endif
}
}
}
...
...
@@ -796,7 +886,11 @@ void sentinelPendingScriptsCommand(redisClient *c) {
(
sj
->
flags
&
SENTINEL_SCRIPT_RUNNING
)
?
"running"
:
"scheduled"
);
addReplyBulkCString
(
c
,
"pid"
);
#ifdef _WIN32
addReplyBulkLongLong
(
c
,
sj
->
processId
);
#else
addReplyBulkLongLong
(
c
,
sj
->
pid
);
#endif
if
(
sj
->
flags
&
SENTINEL_SCRIPT_RUNNING
)
{
addReplyBulkCString
(
c
,
"run-time"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录