diff options
author | Michael Fenn <fennm@deshawresearch.com> | 2014-01-10 11:59:14 -0500 |
---|---|---|
committer | Michael Fenn <fennm@deshawresearch.com> | 2014-01-10 11:59:14 -0500 |
commit | 73979d1482a73da24104950be4bad8f3d50c0754 (patch) | |
tree | ca620ff3d8ba643abdd14dfd1e8293da11428c09 /src | |
parent | deef870d5c8ce3a874878a16abbfb4b126dca4dc (diff) | |
download | bcfg2-73979d1482a73da24104950be4bad8f3d50c0754.tar.gz bcfg2-73979d1482a73da24104950be4bad8f3d50c0754.tar.bz2 bcfg2-73979d1482a73da24104950be4bad8f3d50c0754.zip |
Reporting: occasionally reap child threads
I noticed that, at least on Python 2.4, memory for threads doesn't
get freed until the threads are joined. This patch causes the
collector to periodically go through and reap those threads.
Tested in production for ~1 month, no reported issues.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/Bcfg2/Reporting/Collector.py | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index b42364d8d..52700f917 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -63,6 +63,8 @@ class ReportingCollector(object): self.encoding = setup['encoding'] self.terminate = None self.context = None + self.children = [] + self.cleanup_threshold = 25 if setup['debug']: level = logging.DEBUG @@ -110,6 +112,7 @@ class ReportingCollector(object): self.terminate = threading.Event() atexit.register(self.shutdown) self.context = daemon.DaemonContext(detach_process=True) + iter = 0 if self.setup['daemon']: self.logger.debug("Daemonizing") @@ -133,6 +136,13 @@ class ReportingCollector(object): store_thread = ReportingStoreThread(interaction, self.storage) store_thread.start() + self.children.append(store_thread) + + iter += 1 + if iter >= self.cleanup_threshold: + self.reap_children() + iter = 0 + except (SystemExit, KeyboardInterrupt): self.logger.info("Shutting down") self.shutdown() @@ -152,3 +162,16 @@ class ReportingCollector(object): pass if self.storage: self.storage.shutdown() + + def reap_children(self): + """Join any non-live threads""" + newlist = [] + + self.logger.debug("Starting reap_children") + for child in self.children: + if child.isAlive(): + newlist.append(child) + else: + child.join() + self.logger.debug("Joined child thread %s" % child.getName()) + self.children = newlist |