Skip to content

Commit

Permalink
fix memcache memory leak (#278)
Browse files Browse the repository at this point in the history
Apparently the closure used in parsing the memcache config is
leaving behind some uncollectable objects on each run. Replaced
it with a while loop.
  • Loading branch information
Carlo Cabanilla committed Dec 27, 2012
1 parent 14be4b1 commit 8c62995
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
32 changes: 16 additions & 16 deletions checks/db/mcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
# https://github.com/membase/ep-engine/blob/master/docs/stats.org

class Memcache(Check):
DEFAULT_PORT = 11211

def __init__(self, logger):
Check.__init__(self, logger)
self.gauge("memcache.total_items")
Expand Down Expand Up @@ -102,23 +104,21 @@ def _load_conf(self, agentConfig):
#memcache_instance_1: first_host:first_port:first_tag
#memcache_instance_2: second_host:second_port:second_tag
#memcache_instance_3: third_host:third_port:third_tag
def load_conf(index=1):
index = 1
instance = agentConfig.get("memcache_instance_%s" % index, None)
while instance:
instance = instance.split(":")
memcache_urls.append(instance[0])
if len(instance)>1:
memcache_ports.append(instance[1])
else:
memcache_ports.append(self.DEFAULT_PORT)
if len(instance)==3:
tags.append(instance[2])
else:
tags.append(None)
index = index + 1
instance = agentConfig.get("memcache_instance_%s" % index, None)
if instance is not None:
instance = instance.split(":")
memcache_urls.append(instance[0])
if len(instance)>1:
memcache_ports.append(instance[1])
else:
memcache_ports.append(11211)
if len(instance)==3:
tags.append(instance[2])
else:
tags.append(None)

load_conf(index+1)

load_conf()

return (memcache_urls, memcache_ports, tags)

Expand Down
28 changes: 22 additions & 6 deletions tests/test_mcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
class TestMemCache(unittest.TestCase):
def setUp(self):
self.c = Memcache(logging.getLogger(__file__))
self.agent_config = {
"memcache_server": "localhost",
"memcache_instance_1": "localhost:11211:mytag",
"memcache_instance_2": "dummy:11211:myothertag",
"memcache_instance_3": "localhost:11211:mythirdtag",
}

def _countConnections(self, port):
pid = os.getpid()
Expand All @@ -28,15 +34,25 @@ def testConnectionLeaks(self):

def testMetrics(self):
raise SkipTest("Test is not working anymore on travis boxes. Needs further investigation")
agent_config = {"memcache_server": "localhost",
"memcache_instance_1": "localhost:11211:mytag",
"memcache_instance_2": "dummy:11211:myothertag",
"memcache_instance_3": "localhost:11211:mythirdtag"}
self.c.check(agent_config)
r = self.c.check(agent_config)
self.c.check(self.agent_config)
r = self.c.check(self.agent_config)

self.assertEquals(len([t for t in r if t[0] == "memcache.total_items"]), 3, r)
self.assertEquals(len([t for t in r if t[3].get('tags') == ["instance:mythirdtag"]]), 20, r)

def testMemoryLeak(self):
import gc
gc.set_debug(gc.DEBUG_LEAK)
try:
start = len(gc.garbage)
for i in range(10):
self.c.check(self.agent_config)
end = len(gc.garbage)
self.assertEquals(end - start, 0, gc.garbage)
finally:
gc.set_debug(0)



if __name__ == '__main__':
unittest.main()

1 comment on commit 8c62995

@alq666
Copy link
Member

@alq666 alq666 commented on 8c62995 Dec 27, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@remh fyi

Please sign in to comment.