From 09c239b29480593ff74a1f711e635780a22af7aa Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 3 Jul 2018 08:58:11 -0400 Subject: [PATCH] Fix memory leaks For one, configmanager was left with stale callback references, clean those up. For another, the callback pattern was creating a circular reference that python memory management couldn't overcome. Break the reference explicity when an item is disposed of. --- confluent_server/confluent/consoleserver.py | 3 +++ confluent_server/confluent/plugins/hardwaremanagement/ipmi.py | 1 + confluent_server/confluent/plugins/shell/ssh.py | 2 ++ confluent_server/confluent/shellmodule.py | 1 + 4 files changed, 7 insertions(+) diff --git a/confluent_server/confluent/consoleserver.py b/confluent_server/confluent/consoleserver.py index e952ced6..f8184f93 100644 --- a/confluent_server/confluent/consoleserver.py +++ b/confluent_server/confluent/consoleserver.py @@ -413,6 +413,9 @@ class ConsoleHandler(object): if self.connectionthread: self.connectionthread.kill() self.connectionthread = None + if self._attribwatcher: + self.cfgmgr.remove_watcher(self._attribwatcher) + self._attribwatcher = None def get_console_output(self, data): # Spawn as a greenthread, return control as soon as possible diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index e2e9ecd6..d23afa6c 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -292,6 +292,7 @@ class IpmiConsole(conapi.Console): self.solconnection.out_handler = _donothing self.solconnection.close() self.solconnection = None + self.datacallback = None self.broken = True self.error = "closed" diff --git a/confluent_server/confluent/plugins/shell/ssh.py b/confluent_server/confluent/plugins/shell/ssh.py index 1c6b6182..045912de 100644 --- a/confluent_server/confluent/plugins/shell/ssh.py +++ b/confluent_server/confluent/plugins/shell/ssh.py @@ -63,6 +63,7 @@ class SshShell(conapi.Console): def __init__(self, node, config, username='', password=''): self.node = node self.ssh = None + self.datacallback = None self.nodeconfig = config self.username = username self.password = password @@ -155,6 +156,7 @@ class SshShell(conapi.Console): def close(self): if self.ssh is not None: self.ssh.close() + self.datacallback = None def create(nodes, element, configmanager, inputdata): if len(nodes) == 1: diff --git a/confluent_server/confluent/shellmodule.py b/confluent_server/confluent/shellmodule.py index 08b6a8ef..5b7e44e3 100644 --- a/confluent_server/confluent/shellmodule.py +++ b/confluent_server/confluent/shellmodule.py @@ -116,6 +116,7 @@ class ExecConsole(conapi.Console): break if self.subproc is not None and self.subproc.poll() is None: self.subproc.kill() + self._datacallback = None class Plugin(object):