Commit 09113090 authored by Vincent Pelletier's avatar Vincent Pelletier

Define, handle and advertise shutdown_method option.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@22387 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 705896e0
......@@ -39,6 +39,13 @@ wait_for_close_lock = thread.allocate_lock()
class ClockServer(OriginalClockServer):
running = True
def __init__(self, *args, **kw):
self.shutdown_method = kw.pop('shutdown_method')
OriginalClockServer.__init__(self, *args, **kw)
if self.shutdown_method is None:
self.log_info('ClockServer shutdown_method is not set in configuration'\
'file. Unclean shutdown can happen.', type='warning')
def readable(self):
"""
Avoid starting a new tic if shutdown started.
......@@ -73,31 +80,29 @@ class ClockServer(OriginalClockServer):
closed.
"""
self.running = False
separator = '?' in self.method and '&' or '?'
# XXX: should use a float for time representation
# TODO: allow user to specify a separate shutdown method instead of
# reusing regular one.
method = '%s%sshutdown:int=1&phase:int=%i&time_in_phase:int=%i' % \
(self.method, separator, _shutdown_phase, time_in_this_phase)
if self.shutdown_method is not None:
# XXX: should use a float for time representation
method = '%s?phase:int=%i&time_in_phase:float=%f' % \
(self.shutdown_method, _shutdown_phase, time_in_this_phase)
stdin = StringIO.StringIO()
request_string = 'GET %s HTTP/1.0' % (method, )
request = http_request(DummyChannel(self), request_string, 'GET', method,
'1.0', self.headers)
environment = self.get_env(request)
response = make_response(request, environment)
# Hook response._finish to get a notification when request is over.
def _finish():
response.__class__._finish(response)
stdin = StringIO.StringIO()
request_string = 'GET %s HTTP/1.0' % (method, )
request = http_request(DummyChannel(self), request_string, 'GET', method,
'1.0', self.headers)
environment = self.get_env(request)
response = make_response(request, environment)
# Hook response._finish to get a notification when request is over.
def _finish():
response.__class__._finish(response)
wait_for_close_lock.release()
response._finish = _finish
# (end of hook)
zope_request = HTTPRequest(stdin, environment, response)
wait_for_close_lock.acquire()
self.zhandler('Zope2', zope_request, response)
self.log_info('ClockServer: Waiting for shutdown handler.')
wait_for_close_lock.acquire()
self.log_info('ClockServer: Going on.')
wait_for_close_lock.release()
response._finish = _finish
# (end of hook)
zope_request = HTTPRequest(stdin, environment, response)
wait_for_close_lock.acquire()
self.zhandler('Zope2', zope_request, response)
self.log_info('ClockServer: Waiting for shutdown handler.')
wait_for_close_lock.acquire()
self.log_info('ClockServer: Going on.')
wait_for_close_lock.release()
return 0 # TODO: detect an error to allow taking the veto.
......@@ -29,6 +29,7 @@ ERP5 users: You are strongly encouraged to kee TimerService (but to stop using
timerserver) and use the following configuration:
method /Control_Panel/timer_service/process_timer?interval:int=5
shutdown_method /Control_Panel/timer_service/process_shutdown
period 5
Note: Because ClockServer uses asyncore's "readable" method polling,
......
......@@ -9,6 +9,19 @@
method, etc). The method must take no arguments. Ex: "/site/methodname"
</description>
</key>
<key name="shutdown_method" datatype="string">
<description>
The traversal path (from the Zope root) to an
executable Zope method (Python Script, external method, product
method, etc). The method must take the following arguments:
phase (number)
Shutdown phase number.
See Lifetime.py .
time_in_phase (number)
Time spent in current phase, in seconds.
Given method path must not contain any argument. Ex: "/site/methodname"
</description>
</key>
<key name="period" datatype="integer" default="60">
<description>
The number of seconds between each clock "tick" (and
......
......@@ -18,6 +18,7 @@ class ClockServerFactory(ServerFactory):
def __init__(self, section):
ServerFactory.__init__(self)
self.method = section.method
self.shutdown_method = section.shutdown_method
self.period = section.period
self.user = section.user
self.password = section.password
......@@ -28,5 +29,6 @@ class ClockServerFactory(ServerFactory):
from Products.ClockServer.ClockServer import ClockServer
from ZServer.AccessLogger import access_logger
return ClockServer(self.method, self.period, self.user,
self.password, self.hostheader, access_logger)
self.password, self.hostheader, access_logger,
shutdown_method=self.shutdown_method)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment