Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit214334f

Browse files
committed
Addmax_wait_time setting for the process pool to forcibly terminate worker processes after they time out.
1 parent3f78da5 commit214334f

File tree

11 files changed

+171
-37
lines changed

11 files changed

+171
-37
lines changed

‎ext-src/php_swoole_cxx.cc‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ static const char *sw_known_strings[] = {
1010

1111
SW_API zend_string **sw_zend_known_strings =nullptr;
1212

13+
SW_API zend_refcounted *sw_refcount_ptr;
14+
15+
zend_refcounted *sw_get_refcount_ptr(zval *value) {
16+
return (sw_refcount_ptr = value->value.counted);
17+
}
18+
1319
//----------------------------------known string------------------------------------
1420
namespacezend {
1521
voidknown_strings_init(void) {
@@ -66,4 +72,31 @@ Variable call(const std::string &func_name, int argc, zval *argv) {
6672
}
6773

6874
}// namespace function
75+
76+
Callable::Callable(zval *_zfn) {
77+
ZVAL_UNDEF(&zfn);
78+
if (!zval_is_true(_zfn)) {
79+
php_swoole_fatal_error(E_WARNING,"illegal callback function");
80+
return;
81+
}
82+
if (!sw_zend_is_callable_ex(_zfn,nullptr,0, &fn_name,nullptr, &fcc,nullptr)) {
83+
php_swoole_fatal_error(E_WARNING,"function '%s' is not callable", fn_name);
84+
return;
85+
}
86+
zfn = *_zfn;
87+
zval_add_ref(&zfn);
88+
}
89+
90+
Callable::~Callable() {
91+
if (!ZVAL_IS_UNDEF(&zfn)) {
92+
zval_ptr_dtor(&zfn);
93+
}
94+
if (fn_name) {
95+
efree(fn_name);
96+
}
97+
}
98+
99+
uint32_tCallable::refcount() {
100+
returnzval_refcount_p(&zfn);
101+
}
69102
}// namespace zend

‎ext-src/php_swoole_cxx.h‎

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -593,18 +593,12 @@ class Callable {
593593
Callable() {}
594594

595595
public:
596-
Callable(zval *_zfn) {
597-
ZVAL_UNDEF(&zfn);
598-
if (!zval_is_true(_zfn)) {
599-
php_swoole_fatal_error(E_WARNING,"illegal callback function");
600-
return;
601-
}
602-
if (!sw_zend_is_callable_ex(_zfn,nullptr,0, &fn_name,nullptr, &fcc,nullptr)) {
603-
php_swoole_fatal_error(E_WARNING,"function '%s' is not callable", fn_name);
604-
return;
605-
}
606-
zfn = *_zfn;
607-
zval_add_ref(&zfn);
596+
Callable(zval *_zfn);
597+
~Callable();
598+
uint32_trefcount();
599+
600+
zend_refcounted *refcount_ptr() {
601+
returnsw_get_refcount_ptr(&zfn);
608602
}
609603

610604
zend_fcall_info_cache *ptr() {
@@ -629,15 +623,6 @@ class Callable {
629623
boolcall(uint32_t argc, zval *argv, zval *retval) {
630624
returnsw_zend_call_function_ex(&zfn, &fcc, argc, argv, retval) == SUCCESS;
631625
}
632-
633-
~Callable() {
634-
if (!ZVAL_IS_UNDEF(&zfn)) {
635-
zval_ptr_dtor(&zfn);
636-
}
637-
if (fn_name) {
638-
efree(fn_name);
639-
}
640-
}
641626
};
642627

643628
#define_CONCURRENCY_HASHMAP_LOCK_(code) \

‎ext-src/php_swoole_private.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,8 @@ static inline size_t sw_active_thread_count(void) {
523523
}
524524
#endif
525525

526+
zend_refcounted*sw_get_refcount_ptr(zval*value);
527+
526528
voidsw_php_exit(intstatus);
527529
voidsw_php_print_backtrace(zend_longcid=0,
528530
zend_longoptions=0,

‎ext-src/php_swoole_process.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ void php_swoole_process_clean();
2424
intphp_swoole_process_start(swoole::Worker*process,zval*zobject);
2525
swoole::Worker*php_swoole_process_get_worker(zval*zobject);
2626
voidphp_swoole_process_set_worker(zval*zobject,swoole::Worker*worker);
27+
28+
swoole::ProcessPool*sw_process_pool();

‎ext-src/swoole_process_pool.cc‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ static void process_pool_onWorkerStart(ProcessPool *pool, Worker *worker) {
169169
zend_update_property_long(swoole_process_pool_ce,SW_Z8_OBJ_P(zobject),ZEND_STRL("workerPid"),getpid());
170170
zend_update_property_long(swoole_process_pool_ce,SW_Z8_OBJ_P(zobject),ZEND_STRL("workerId"), worker->id);
171171

172+
swoole_set_process_type(SW_PROCESS_WORKER);
173+
SwooleG.enable_coroutine = pp->enable_coroutine;
174+
172175
if (pp->onWorkerStart) {
173176
zval args[2];
174177
args[0] = *zobject;
@@ -259,6 +262,9 @@ static void process_pool_onStart(ProcessPool *pool) {
259262
zend_update_property_long(swoole_process_pool_ce,SW_Z8_OBJ_P(zobject),ZEND_STRL("master_pid"),getpid());
260263
zend_update_property_bool(swoole_process_pool_ce,SW_Z8_OBJ_P(zobject),ZEND_STRL("running"),true);
261264

265+
swoole_set_process_type(SW_PROCESS_MASTER);
266+
SwooleG.enable_coroutine =false;
267+
262268
if (pp->onStart ==nullptr) {
263269
return;
264270
}
@@ -312,6 +318,10 @@ static void process_pool_signal_handler(int sig) {
312318
}
313319
}
314320

321+
ProcessPool *sw_process_pool() {
322+
return current_pool;
323+
}
324+
315325
staticPHP_METHOD(swoole_process_pool, __construct) {
316326
zval *zobject = ZEND_THIS;
317327
zend_long worker_num;
@@ -321,15 +331,31 @@ static PHP_METHOD(swoole_process_pool, __construct) {
321331

322332
// only cli env
323333
if (!SWOOLE_G(cli)) {
334+
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
324335
zend_throw_error(NULL,"%s can only be used in PHP CLI mode",SW_Z_OBJCE_NAME_VAL_P(zobject));
325336
RETURN_FALSE;
326337
}
327338

328339
if (sw_server()) {
329-
zend_throw_error(NULL,"%s cannot use in server process",SW_Z_OBJCE_NAME_VAL_P(zobject));
340+
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
341+
zend_throw_error(NULL,"cannot create server and process pool instances simultaneously");
330342
RETURN_FALSE;
331343
}
332344

345+
if (sw_process_pool()) {
346+
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
347+
zend_throw_error(NULL,"A process pool instance has already been created and cannot be created again");
348+
RETURN_FALSE;
349+
}
350+
351+
#ifdef SW_THREAD
352+
if (!tsrm_is_main_thread()) {
353+
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
354+
zend_throw_exception_ex(swoole_exception_ce, -1,"This operation is only allowed in the main thread");
355+
RETURN_FALSE;
356+
}
357+
#endif
358+
333359
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(),"l|llb", &worker_num, &ipc_type, &msgq_key, &enable_coroutine) ==
334360
FAILURE) {
335361
RETURN_FALSE;
@@ -390,6 +416,10 @@ static PHP_METHOD(swoole_process_pool, set) {
390416
if (php_swoole_array_get_value(vht,"max_package_size", ztmp)) {
391417
pool->set_max_packet_size(php_swoole_parse_to_size(ztmp));
392418
}
419+
if (php_swoole_array_get_value(vht,"max_wait_time", ztmp)) {
420+
zend_long v =zval_get_long(ztmp);
421+
pool->max_wait_time =SW_MAX(0,SW_MIN(v, UINT32_MAX));
422+
}
393423
}
394424

395425
staticPHP_METHOD(swoole_process_pool, on) {

‎ext-src/swoole_server.cc‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2659,7 +2659,7 @@ static PHP_METHOD(swoole_server, start) {
26592659
RETURN_FALSE;
26602660
}
26612661

2662-
if (SwooleTG.reactor) {
2662+
if (sw_reactor()) {
26632663
php_swoole_fatal_error(
26642664
E_WARNING,"eventLoop has already been created, unable to start %s",SW_Z_OBJCE_NAME_VAL_P(zserv));
26652665
RETURN_FALSE;

‎ext-src/swoole_timer.cc‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include"php_swoole_cxx.h"
20+
#include"php_swoole_process.h"
2021

2122
#include"swoole_server.h"
2223

@@ -148,6 +149,18 @@ static void timer_callback(Timer *timer, TimerNode *tnode) {
148149
}
149150
}
150151

152+
staticbooltimer_if_use_reactor() {
153+
auto server =sw_server();
154+
if (server) {
155+
return server->is_user_worker() || (server->is_task_worker() && server->task_enable_coroutine);
156+
}
157+
auto process_pool =sw_process_pool();
158+
if (process_pool) {
159+
return !process_pool->is_master();
160+
}
161+
returntrue;
162+
}
163+
151164
staticvoidtimer_add(INTERNAL_FUNCTION_PARAMETERS,bool persistent) {
152165
zend_long ms;
153166
Function *fci = (Function *)ecalloc(1,sizeof(Function));
@@ -166,9 +179,7 @@ static void timer_add(INTERNAL_FUNCTION_PARAMETERS, bool persistent) {
166179
RETURN_FALSE;
167180
}
168181

169-
// no server || user worker || task process with async mode
170-
if (!sw_server() ||sw_server()->is_user_worker() ||
171-
(sw_server()->is_task_worker() &&sw_server()->task_enable_coroutine)) {
182+
if (UNEXPECTED(!sw_reactor() &&timer_if_use_reactor())) {
172183
php_swoole_check_reactor();
173184
}
174185

‎include/swoole_process_pool.h‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ struct ProcessPool {
327327
max_packet_size_ = _max_packet_size;
328328
}
329329

330+
boolis_master() {
331+
returnswoole_get_process_type() == SW_PROCESS_MASTER;
332+
}
333+
334+
boolis_worker() {
335+
returnswoole_get_process_type() == SW_PROCESS_WORKER;
336+
}
337+
330338
voidset_protocol(enum ProtocolType _protocol_type);
331339

332340
voidset_max_request(uint32_t _max_request,uint32_t _max_request_grace);
@@ -339,6 +347,7 @@ struct ProcessPool {
339347
boolreload();
340348
pid_tspawn(Worker *worker);
341349
voidstop(Worker *worker);
350+
voidkill_all_workers(int signo = SIGKILL);
342351
swResultCodedispatch(EventData *data,int *worker_id);
343352
intresponse(constchar *data,int length);
344353
swResultCodedispatch_blocking(EventData *data,int *dst_worker_id);

‎src/core/timer.cc‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ bool Timer::init() {
6969
}
7070

7171
boolTimer::init_with_user_scheduler(const TimerScheduler &scheduler) {
72-
set = [&scheduler](Timer *timer,long exec_msec) ->int {
73-
returnscheduler(timer, exec_msec);
74-
};
72+
set = [&scheduler](Timer *timer,long exec_msec) ->int {returnscheduler(timer, exec_msec); };
7573
close = [&scheduler](Timer *timer) {scheduler(timer, -1); };
7674
returntrue;
7775
}
@@ -236,6 +234,7 @@ int Timer::select() {
236234
heap.pop();
237235
map.erase(tnode->id);
238236
delete tnode;
237+
tnode =nullptr;
239238
}
240239

241240
if (!tnode || !tmp) {

‎src/os/process_pool.cc‎

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ int ProcessPool::create(uint32_t _worker_num, key_t _msgqueue_key, swIPCMode _ip
122122
main_loop = run_with_task_protocol;
123123
protocol_type_ = SW_PROTOCOL_TASK;
124124
max_packet_size_ = SW_INPUT_BUFFER_SIZE;
125+
max_wait_time = SW_WORKER_MAX_WAIT_TIME;
125126

126127
SW_LOOP_N(_worker_num) {
127128
workers[i].pool =this;
@@ -444,6 +445,12 @@ void ProcessPool::stop(Worker *worker) {
444445
}
445446
}
446447

448+
voidProcessPool::kill_all_workers(int signo) {
449+
SW_LOOP_N(worker_num) {
450+
swoole_kill(workers[i].pid, signo);
451+
}
452+
}
453+
447454
voidProcessPool::shutdown() {
448455
uint32_t i;
449456
int status;
@@ -462,10 +469,20 @@ void ProcessPool::shutdown() {
462469
continue;
463470
}
464471
}
472+
if (max_wait_time) {
473+
swoole_timer_add((long) max_wait_time *1000,false, [this](Timer *, TimerNode *) {kill_all_workers(); });
474+
}
465475
for (i =0; i < worker_num; i++) {
466476
worker = &workers[i];
467-
if (swoole_waitpid(worker->pid, &status,0) <0) {
468-
swoole_sys_warning("waitpid(%d) failed", worker->pid);
477+
SW_LOOP {
478+
if (waitpid(worker->pid, &status,0) <0) {
479+
if (errno == EINTR) {
480+
sw_timer()->select();
481+
continue;
482+
}
483+
swoole_sys_warning("waitpid(%d) failed", worker->pid);
484+
}
485+
break;
469486
}
470487
}
471488
started =false;
@@ -853,7 +870,6 @@ bool ProcessPool::detach() {
853870

854871
intProcessPool::wait() {
855872
pid_t new_pid, reload_worker_pid =0;
856-
int ret;
857873

858874
while (running) {
859875
ExitStatus exit_status =wait_process();
@@ -892,7 +908,7 @@ int ProcessPool::wait() {
892908
}
893909
if (!reloading) {
894910
if (errno >0 && errno != EINTR) {
895-
swoole_sys_warning("[Manager]wait failed");
911+
swoole_sys_warning("wait() failed");
896912
}
897913
continue;
898914
}else {
@@ -913,7 +929,7 @@ int ProcessPool::wait() {
913929
if (onWorkerNotFound) {
914930
onWorkerNotFound(this, exit_status);
915931
}else {
916-
swoole_warning("[Manager]unknown worker[pid=%d]", exit_status.get_pid());
932+
swoole_warning("unknown worker[pid=%d]", exit_status.get_pid());
917933
}
918934
continue;
919935
}
@@ -944,13 +960,12 @@ int ProcessPool::wait() {
944960
continue;
945961
}
946962
reload_worker_pid = reload_workers[reload_worker_i].pid;
947-
ret =swoole_kill(reload_worker_pid, SIGTERM);
948-
if (ret <0) {
963+
if (swoole_kill(reload_worker_pid, SIGTERM) <0) {
949964
if (errno == ECHILD) {
950965
reload_worker_i++;
951966
goto _kill_worker;
952967
}
953-
swoole_sys_warning("[Manager]swKill(%d) failed", reload_workers[reload_worker_i].pid);
968+
swoole_sys_warning("kill(%d) failed", reload_workers[reload_worker_i].pid);
954969
continue;
955970
}
956971
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp