summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Fenn <fennm@deshawresearch.com>2014-01-10 11:59:14 -0500
committerMichael Fenn <fennm@deshawresearch.com>2014-01-10 11:59:14 -0500
commit73979d1482a73da24104950be4bad8f3d50c0754 (patch)
treeca620ff3d8ba643abdd14dfd1e8293da11428c09
parentdeef870d5c8ce3a874878a16abbfb4b126dca4dc (diff)
downloadbcfg2-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.
-rw-r--r--src/lib/Bcfg2/Reporting/Collector.py23
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