From 21822f259cfa608c31a1a365ffc17398b3eef125 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 2 Nov 2014 14:30:06 -0800 Subject: [PATCH] Significantly improve speed of PC list updates --- app/libs/limelight-common.jar | Bin 423963 -> 418419 bytes .../computers/ComputerManagerService.java | 206 ++++++++++-------- 2 files changed, 111 insertions(+), 95 deletions(-) diff --git a/app/libs/limelight-common.jar b/app/libs/limelight-common.jar index 14f5ebbb4c712206cf9e904c53b5458f1c1819bc..fe52a2357cade0ebcd8d137e8e8c29590ab27290 100644 GIT binary patch delta 10450 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 L0(lEsA&~z8+&#^# delta 16056 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%0DjO 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 W+JK30bP#k9dVt5Vv%b^m>xy| diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index 2a2bcd84..3edd1027 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -1,6 +1,7 @@ package com.limelight.computers; import java.net.InetAddress; +import java.util.HashMap; import java.util.List; import java.util.Timer; import java.util.TimerTask; @@ -25,7 +26,6 @@ import android.os.Binder; import android.os.IBinder; public class ComputerManagerService extends Service { - private static final int MAX_CONCURRENT_REQUESTS = 4; private static final int POLLING_PERIOD_MS = 5000; private static final int MDNS_QUERY_PERIOD_MS = 1000; @@ -35,8 +35,7 @@ public class ComputerManagerService extends Service { private AtomicInteger dbRefCount = new AtomicInteger(0); private IdentityManager idManager; - private ThreadPoolExecutor pollingPool; - private Timer pollingTimer; + private HashMap pollingThreads; private ComputerManagerListener listener = null; private AtomicInteger activePolls = new AtomicInteger(0); private boolean stopped; @@ -60,6 +59,85 @@ public class ComputerManagerService extends Service { discoveryBinder = null; } }; + + // Returns true if the details object was modified + private boolean runPoll(ComputerDetails details) + { + boolean newPc = (details.name == null); + + // This is called from addComputerManually() where we don't + // want to block the initial poll if polling is disabled, so + // we explicitly let this through if we've never seen this + // PC before. This path won't be triggered normally when polling + // is disabled because the mDNS discovery is stopped. + if (stopped && !newPc) { + return false; + } + + if (!getLocalDatabaseReference()) { + return false; + } + + activePolls.incrementAndGet(); + + // Poll the machine + if (!doPollMachine(details)) { + details.state = ComputerDetails.State.OFFLINE; + details.reachability = ComputerDetails.Reachability.OFFLINE; + } + + activePolls.decrementAndGet(); + + // If it's online, update our persistent state + if (details.state == ComputerDetails.State.ONLINE) { + if (!newPc) { + // Check if it's in the database because it could have been + // removed after this was issued + if (dbManager.getComputerByName(details.name) == null) { + // It's gone + releaseLocalDatabaseReference(); + return true; + } + } + + dbManager.updateComputer(details); + } + + // Don't call the listener if this is a failed lookup of a new PC + if ((!newPc || details.state == ComputerDetails.State.ONLINE) && listener != null) { + listener.notifyComputerUpdated(details); + } + + releaseLocalDatabaseReference(); + return true; + } + + private Thread createPollingThread(final ComputerDetails details) { + Thread t = new Thread() { + @Override + public void run() { + while (!isInterrupted()) { + ComputerDetails originalDetails = new ComputerDetails(); + originalDetails.update(details); + + // Check if this poll has modified the details + if (runPoll(details) && !originalDetails.equals(details)) { + // Replace our thread entry with the new one + synchronized (pollingThreads) { + pollingThreads.remove(originalDetails); + pollingThreads.put(details, this); + } + } + + // Wait until the next polling interval + try { + Thread.sleep(POLLING_PERIOD_MS); + } catch (InterruptedException e) {} + } + } + }; + return t; + } public class ComputerManagerBinder extends Binder { public void startPolling(ComputerManagerListener listener) { @@ -73,8 +151,19 @@ public class ComputerManagerService extends Service { discoveryBinder.startDiscovery(MDNS_QUERY_PERIOD_MS); // Start polling known machines - pollingTimer = new Timer(); - pollingTimer.schedule(getTimerTask(), 0, POLLING_PERIOD_MS); + if (!getLocalDatabaseReference()) { + return; + } + List computerList = dbManager.getAllComputers(); + releaseLocalDatabaseReference(); + + synchronized (pollingThreads) { + for (ComputerDetails computer : computerList) { + Thread t = createPollingThread(computer); + pollingThreads.put(computer, t); + t.start(); + } + } } public void waitForReady() { @@ -128,10 +217,11 @@ public class ComputerManagerService extends Service { discoveryBinder.stopDiscovery(); // Stop polling - if (pollingTimer != null) { - pollingTimer.cancel(); - pollingTimer = null; - } + synchronized (pollingThreads) { + for (Thread t : pollingThreads.values()) { + t.interrupt(); + } + } // Remove the listener listener = null; @@ -159,17 +249,21 @@ public class ComputerManagerService extends Service { } }; } - + public void addComputer(InetAddress addr) { // Setup a placeholder ComputerDetails fakeDetails = new ComputerDetails(); fakeDetails.localIp = addr; fakeDetails.remoteIp = addr; - - // Put it in the thread pool to process later - pollingPool.execute(getPollingRunnable(fakeDetails)); + + // Spawn a thread for this computer + synchronized (pollingThreads) { + Thread t = createPollingThread(fakeDetails); + pollingThreads.put(fakeDetails, t); + t.start(); + } } - + public boolean addComputerBlocking(InetAddress addr) { // Setup a placeholder ComputerDetails fakeDetails = new ComputerDetails(); @@ -177,7 +271,7 @@ public class ComputerManagerService extends Service { fakeDetails.remoteIp = addr; // Block while we try to fill the details - getPollingRunnable(fakeDetails).run(); + runPoll(fakeDetails); // If the machine is reachable, it was successful return fakeDetails.state == ComputerDetails.State.ONLINE; @@ -209,23 +303,6 @@ public class ComputerManagerService extends Service { } } - private TimerTask getTimerTask() { - return new TimerTask() { - @Override - public void run() { - if (!getLocalDatabaseReference()) { - return; - } - List computerList = dbManager.getAllComputers(); - releaseLocalDatabaseReference(); - - for (ComputerDetails computer : computerList) { - pollingPool.execute(getPollingRunnable(computer)); - } - } - }; - } - private ComputerDetails tryPollIp(InetAddress ipAddr) { try { NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(), @@ -281,71 +358,13 @@ public class ComputerManagerService extends Service { return pollComputer(details, true); } - private Runnable getPollingRunnable(final ComputerDetails details) { - return new Runnable() { - - @Override - public void run() { - boolean newPc = (details.name == null); - - // This is called from addComputerManually() where we don't - // want to block the initial poll if polling is disabled, so - // we explicitly let this through if we've never seen this - // PC before. This path won't be triggered normally when polling - // is disabled because the mDNS discovery is stopped. - if (stopped && !newPc) { - return; - } - - if (!getLocalDatabaseReference()) { - return; - } - - activePolls.incrementAndGet(); - - // Poll the machine - if (!doPollMachine(details)) { - details.state = ComputerDetails.State.OFFLINE; - details.reachability = ComputerDetails.Reachability.OFFLINE; - } - - activePolls.decrementAndGet(); - - // If it's online, update our persistent state - if (details.state == ComputerDetails.State.ONLINE) { - if (!newPc) { - // Check if it's in the database because it could have been - // removed after this was issued - if (dbManager.getComputerByName(details.name) == null) { - // It's gone - releaseLocalDatabaseReference(); - return; - } - } - - dbManager.updateComputer(details); - } - - // Don't call the listener if this is a failed lookup of a new PC - if ((!newPc || details.state == ComputerDetails.State.ONLINE) && listener != null) { - listener.notifyComputerUpdated(details); - } - - releaseLocalDatabaseReference(); - } - }; - } - @Override public void onCreate() { // Bind to the discovery service bindService(new Intent(this, DiscoveryService.class), discoveryServiceConnection, Service.BIND_AUTO_CREATE); - - // Create the thread pool for updating computer state - pollingPool = new ThreadPoolExecutor(MAX_CONCURRENT_REQUESTS, MAX_CONCURRENT_REQUESTS, - Long.MAX_VALUE, TimeUnit.DAYS, new LinkedBlockingQueue(), - new ThreadPoolExecutor.DiscardPolicy()); + + pollingThreads = new HashMap(); // Lookup or generate this device's UID idManager = new IdentityManager(this); @@ -362,9 +381,6 @@ public class ComputerManagerService extends Service { unbindService(discoveryServiceConnection); } - // Stop the thread pool - pollingPool.shutdownNow(); - // FIXME: Should await termination here but we have timeout issues in HttpURLConnection // Remove the initial DB reference