Rev 5: 'apache2' can't be relied upon to ensure server is started or in file:///v/home/vila/.bazaar/plugins/local_test_server/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed May 28 10:15:09 BST 2008
At file:///v/home/vila/.bazaar/plugins/local_test_server/
------------------------------------------------------------
revno: 5
revision-id: v.ladeuil+lp at free.fr-20080528091508-y8f72o1afg1zhxsd
parent: v.ladeuil+lp at free.fr-20080528082712-cbye8jpu0qxvz1rf
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: local_test_server
timestamp: Wed 2008-05-28 11:15:08 +0200
message:
'apache2' can't be relied upon to ensure server is started or
stopped.
* server.py:
(Apache2): Refactored now that we got a better understanding of
the issues.
modified:
server.py server.py-20080524160639-rqhbexqatjqbwypw-1
-------------- next part --------------
=== modified file 'server.py'
--- a/server.py 2008-05-28 08:27:12 +0000
+++ b/server.py 2008-05-28 09:15:08 +0000
@@ -42,10 +42,6 @@
def is_running(self):
raise NotImplementedError(self.is_running)
- @property
- def pid(self):
- raise NotImplementedError(self.pid)
-
def get_config_value(self, name, default=None):
return self.config.get_value(name, default)
@@ -66,8 +62,16 @@
f.close()
return content
+
class Apache2(Server):
+ # Sometimes we need to let apache2 do its house keeping (hk) to be sure
+ # some commands are really taken into account.
+ _hk_delay = 10 # in seconds
+ # We poll at regular intervals to achieve that, for lack of a better
+ # alternative
+ _hk_interval = 10.0 # in miliseconds
+
def __init__(self):
super(Apache2, self).__init__(config.Apache2())
self.port = None
@@ -83,57 +87,79 @@
outfile.close()
subprocess.check_call(['apache2', '-k', 'start',
'-f', config_filename ])
- self._wait_for_pidfile_to_be_created()
+ if not self._wait_for_pidfile_to_be_created():
+ raise errors.BzrCommandError('apache2 cannot be atarted')
- def _wait_for_pidfile_to_be_created(self):
- # I couldn't find a a way/command/parameter to start apache2 so that
- # pidfile file is created when the command returns. Then, if the server
- # fails to start no pidfile is ever created. Damn if you wait, damn if
- # you wait too long ;-)
- started = False
- delay = 0.001 # 10 ms
- # total delay to wait in seconds, if you experienced a longer start
- # time, well, increase.
- total_delay = 2
- for i in range(0, int(total_delay * (1 / delay))):
- if self.is_running():
- break
- else:
- time.sleep(delay)
def stop(self):
config_filename = config.get_lts_path('etc/apache2.conf')
- pid = self.pid
+ pid = self.get_pid()
# Tell it to stop
subprocess.call(['apache2', '-k', 'stop',
'-f', config_filename ])
# But of course, it's not enough
- self._wait_for_pid_death(pid)
+ if not self._wait_for_pid_death(pid):
+ raise errors.BzrCommandError(
+ 'apache2 cannot be stopped pid: %s' % pid)
+
+ def _hk_poll(self, verified, delay=None, interval=None):
+ """Poll for a condition to be verified until delay expired.
+
+ :param verified: A callable retuning True if the desired condition is
+ verified.
+ :param delay: How long to try (in seconds).
+ :param interval: How often to try (in miliseconds).
+
+ :return: True if the condition is verified, False if the delay expires.
+ """
+ if delay is None:
+ delay = self._hk_delay
+ if interval is None:
+ interval = self._hk_interval
+
+ interval = interval / 1000 # Convert to seconds
+ nb_polls = int(delay * (1 / interval))
+
+ for i in range(0, nb_polls):
+ if verified():
+ return True
+ time.sleep(interval)
+
+ return False
+
+ def _wait_for_pidfile_to_be_created(self):
+ """Reliably check that the server is started.
+
+ apache2 returns early when running the '-k start' command. This doesn't
+ guarantee that the server is started. We need to poll the pidfile
+ creation for that.
+ """
+ return self._hk_poll(self.is_running)
def _wait_for_pid_death(self, pid):
- # After apache2 is stopped, ensure the corresponding processes are
- # really dead.
- started = False
- delay = 0.001 # 10 ms
- # total delay to wait in seconds, if you experienced a longer start
- # time, well, increase.
- total_delay = 2
- for i in range(0, int(total_delay * (1 / delay))):
+ """Reliably check that the server has stopped.
+
+ apache2 returns early when running the '-k stop' command. This doesn't
+ guarantee that the server is stopped. We need to check that the main
+ process is dead.
+ """
+ def server_is_dead():
try:
os.kill(pid, 0)
except OSError, e:
if e.errno == errno.ESRCH:
- # Good, finally it's dead
- break
+ # The process doesn't exist anymore
+ return True
else:
raise
- time.sleep(delay)
+ return False
+
+ return self._hk_poll(server_is_dead)
def is_running(self):
- return bool(self.pid is not None)
+ return bool(self.get_pid() is not None)
- @property
- def pid(self):
+ def get_pid(self):
try:
content = self._get_file_content(self.get_config_value('pid_file'))
except errors.NoSuchFile:
More information about the bazaar-commits
mailing list