From 6373eea1f7d1b32b926d9d59eb8accc0c40a2a41 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Sat, 7 Apr 2012 22:21:32 -0400 Subject: [PATCH] docstrings in Bot; daemonize wiki_scheduler --- earwigbot/bot.py | 35 ++++++++++++++++++++++++++--------- earwigbot/irc/connection.py | 4 ++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/earwigbot/bot.py b/earwigbot/bot.py index 071cca2..9a1bc79 100644 --- a/earwigbot/bot.py +++ b/earwigbot/bot.py @@ -69,6 +69,7 @@ class Bot(object): self.tasks.load() def _start_irc_components(self): + """Start the IRC frontend/watcher in separate threads if enabled.""" if self.config.components.get("irc_frontend"): self.logger.info("Starting IRC frontend") self.frontend = Frontend(self) @@ -80,6 +81,7 @@ class Bot(object): Thread(name="irc_watcher", target=self.watcher.loop).start() def _start_wiki_scheduler(self): + """Start the wiki scheduler in a separate thread if enabled.""" def wiki_scheduler(): while self._keep_looping: time_start = time() @@ -91,15 +93,27 @@ class Bot(object): if self.config.components.get("wiki_scheduler"): self.logger.info("Starting wiki scheduler") - Thread(name="wiki_scheduler", target=wiki_scheduler).start() + thread = Thread(name="wiki_scheduler", target=wiki_scheduler) + thread.daemon = True # Stop if other threads stop + thread.start() def _stop_irc_components(self): + """Request the IRC frontend and watcher to stop if enabled.""" if self.frontend: self.frontend.stop() if self.watcher: self.watcher.stop() - def _loop(self): + def run(self): + """Main entry point into running the bot. + + Starts all config-enabled components and then enters an idle loop, + ensuring that all components remain online and restarting components + that get disconnected from their servers. + """ + self.logger.info("Starting bot") + self._start_irc_components() + self._start_wiki_scheduler() while self._keep_looping: with self.component_lock: if self.frontend and self.frontend.is_stopped(): @@ -110,15 +124,17 @@ class Bot(object): self.logger.warn("IRC watcher has stopped; restarting") self.watcher = Watcher(self) Thread(name=name, target=self.watcher.loop).start() - sleep(3) - - def run(self): - self.logger.info("Starting bot") - self._start_irc_components() - self._start_wiki_scheduler() - self._loop() + sleep(2) def restart(self): + """Reload config, commands, tasks, and safely restart IRC components. + + This is thread-safe, and it will gracefully stop IRC components before + reloading anything. Note that you can safely reload commands or tasks + without restarting the bot with bot.commands.load() or + bot.tasks.load(). These should not interfere with running components + or tasks. + """ self.logger.info("Restarting bot per request from owner") with self.component_lock: self._stop_irc_components() @@ -128,6 +144,7 @@ class Bot(object): self._start_irc_components() def stop(self): + """Gracefully stop all bot components.""" self.logger.info("Shutting down bot") with self.component_lock: self._stop_irc_components() diff --git a/earwigbot/irc/connection.py b/earwigbot/irc/connection.py index 7e2bb19..62b0455 100644 --- a/earwigbot/irc/connection.py +++ b/earwigbot/irc/connection.py @@ -147,10 +147,10 @@ class IRCConnection(object): self._close() break - def stop(self): + def stop(self, msg=None): """Request the IRC connection to close at earliest convenience.""" if self._is_running: - self.quit() + self.quit(msg) self._is_running = False def is_stopped(self):