1
1
#-----------------------------------------------------------
2
2
# Threaded, Gevent and Prefork Servers
3
3
#-----------------------------------------------------------
4
+ import ctypes
4
5
import datetime
5
6
import errno
6
7
import logging
7
8
import os
8
9
import os .path
9
10
import platform
10
11
import random
12
+ import requests
11
13
import select
12
14
import signal
13
15
import socket
@@ -826,7 +828,10 @@ def process_timeout(self):
826
828
worker .__class__ .__name__ ,
827
829
pid ,
828
830
worker .watchdog_timeout )
829
- self .worker_kill (pid , signal .SIGKILL )
831
+ if (now - worker .watchdog_time ) >= worker .watchdog_timeout + 5 :
832
+ self .worker_kill (pid , signal .SIGKILL )
833
+ else :
834
+ self .worker_kill (pid , signal .SIGABRT )
830
835
831
836
def process_spawn (self ):
832
837
if config ['http_enable' ]:
@@ -946,6 +951,7 @@ def __init__(self, multi):
946
951
self .ppid = os .getpid ()
947
952
self .pid = None
948
953
self .alive = True
954
+ self .thread = None
949
955
# should we rename into lifetime ?
950
956
self .request_max = multi .limit_request
951
957
self .request_count = 0
@@ -969,6 +975,24 @@ def signal_time_expired_handler(self, n, stack):
969
975
# We dont suicide in such case
970
976
raise Exception ('CPU time limit exceeded.' )
971
977
978
+ def signal_time_real_handler (self , sig , frame ):
979
+ _logger .info ('Worker (%d) real time limit (%s) reached.' , self .pid , config ['limit_time_real' ])
980
+ thread_id = None
981
+ if hasattr (self .thread , '_thread_id' ):
982
+ thread_id = self .thread ._thread_id
983
+ for id , thread in threading ._active .items ():
984
+ if thread is self .thread :
985
+ thread_id = id
986
+ if not thread_id :
987
+ raise Exception ('Failed to determine thread id.' )
988
+
989
+ res = ctypes .pythonapi .PyThreadState_SetAsyncExc (thread_id , ctypes .py_object (SystemExit ))
990
+ if res > 1 :
991
+ ctypes .pythonapi .PyThreadState_SetAsyncExc (thread_id , 0 )
992
+ # print('Exception raise failure')
993
+
994
+ # raise Exception('Real time limit exceeded.')
995
+
972
996
def sleep (self ):
973
997
try :
974
998
select .select ([self .multi .socket , self .wakeup_fd_r ], [], [], self .multi .beat )
@@ -1017,6 +1041,7 @@ def start(self):
1017
1041
# reset blocking status
1018
1042
self .multi .socket .setblocking (0 )
1019
1043
1044
+ signal .signal (signal .SIGABRT , self .signal_time_real_handler )
1020
1045
signal .signal (signal .SIGINT , self .signal_handler )
1021
1046
signal .signal (signal .SIGXCPU , self .signal_time_expired_handler )
1022
1047
@@ -1034,10 +1059,10 @@ def stop(self):
1034
1059
def run (self ):
1035
1060
try :
1036
1061
self .start ()
1037
- t = threading .Thread (name = "Worker %s (%s) workthread" % (self .__class__ .__name__ , self .pid ), target = self ._runloop )
1038
- t .daemon = True
1039
- t .start ()
1040
- t .join ()
1062
+ self . thread = threading .Thread (name = "Worker %s (%s) workthread" % (self .__class__ .__name__ , self .pid ), target = self ._runloop )
1063
+ self . thread .daemon = True
1064
+ self . thread .start ()
1065
+ self . thread .join ()
1041
1066
_logger .info ("Worker (%s) exiting. request_count: %s, registry count: %s." ,
1042
1067
self .pid , self .request_count ,
1043
1068
len (odoo .modules .registry .Registry .registries ))
0 commit comments