package com.topsy.jmxproxy.jmx;

import com.topsy.jmxproxy.core.Host;

import com.yammer.dropwizard.lifecycle.Managed;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConnectionManager implements Managed {
    private static final Logger LOG = LoggerFactory.getLogger(ConnectionManager.class);

    private Map<String, ConnectionWorker> hosts;
    private boolean started = false;

    public ConnectionManager() {
        hosts = new HashMap<String, ConnectionWorker>();
    }

    public Host getHost(String host) throws Exception {
        synchronized (hosts) {
            if (!hosts.containsKey(host)) {
                LOG.info("creating new worker for " + host);
                hosts.put(host, new ConnectionWorker(host));
            }
        }

        return hosts.get(host).getHost();
    }

    public boolean isStarted() {
        return started;
    }

    public void start() {
        LOG.info("starting jmx connection manager");
        started = true;
    }

    public void stop() {
        LOG.info("stopping jmx connection manager");
        started = false;
        hosts.clear();
    }
}

@@ -162,16 +162,148 @@
 l.Map;%0A%0A
+import java.util.concurrent.Executors;%0Aimport java.util.concurrent.ScheduledExecutorService;%0Aimport java.util.concurrent.TimeUnit;%0A%0A
 import o
@@ -319,16 +319,16 @@
 Logger;%0A
-
 import o
@@ -542,16 +542,61 @@
  hosts;%0A
+    private ScheduledExecutorService purge;%0A%0A
     priv
@@ -711,24 +711,86 @@
 nWorker%3E();%0A
+        purge = Executors.newSingleThreadScheduledExecutor();%0A
     %7D%0A%0A    p
@@ -1245,32 +1245,695 @@
 ction manager%22);
+%0A%0A        purge.scheduleAtFixedRate(new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                LOG.debug(%22begin expiring stale hosts%22);%0A                synchronized (hosts) %7B%0A                    for (Map.Entry%3CString, ConnectionWorker%3EhostEntry : hosts.entrySet()) %7B%0A                        if (hostEntry.getValue().isExpired()) %7B%0A                            LOG.debug(%22purging %22 + hostEntry.getKey());%0A                            hosts.remove(hostEntry.getKey());%0A                        %7D%0A                    %7D%0A                %7D%0A                LOG.debug(%22end expiring stale hosts%22);%0A            %7D%0A        %7D, 1, 1, TimeUnit.MINUTES);
 %0A        started
@@ -2038,46 +2038,72 @@
     
-started = false;%0A        hosts.clear()
+purge.shutdown();%0A        hosts.clear();%0A        started = false
 ;%0A  

Add a purge thread that periodically removes stale connection workers to prevent user-induced memory leaks.