@SuppressWarnings("boxing") @Thread(isDaemonic = true) public void backgroundInit() { // (Ralf:) zomfg, this is one of the worst hacks i've done the last // couple of months. Deep within jmdns we placed a variable to // override a check if it is already save to transmit something. jmDNS // usually takes 5 seconds to reach that state, but that's // too long for us. If you set this variable the check will be skipped // and the request should take place much faster. // Appears to work(tm). ServiceResolver.ANNOUNCE_OVERRIDE = true; final PluginConfigurationUtil pcu = new PluginConfigurationUtil(this.pluginConfiguration); this.startupLock = pcu.getInt(RemoteDiscovery.class, "startup.locktime", 1000); this.lockMode = pcu.getString(RemoteDiscovery.class, "startup.lockmode", "onepass"); // TODO put this in a thread this.checkCache.loadCache(); try { this.jmdnsLock.lock(); this.jmdns = JmDNS .create(); // Maybe init with local loopback in case no other network card is present, // otherwise returns null this.timeOfStartup = System.currentTimeMillis(); final int port = getFreePort(); final ServiceInfo service = ServiceInfo.create(TYPE, NAME + " @" + this.timeOfStartup, port, 0, 0, EXPORT_NAME); this.localManagerExportServer = Proxies.newServer(EXPORT_NAME, port, (DiscoveryManager) this.localManager); this.jmdns.registerService(service); // Set it again, this time for the lock below this.timeOfStartup = System.currentTimeMillis(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalStateException e) { this.logger.warning("Error starting discovery."); } finally { this.startupLatch.countDown(); this.jmdnsLock.unlock(); } // and load our cache... // todo make this configurable... // this.checkCache.loadCache(fileName) }
@SuppressWarnings("boxing") public void backgroundInit() { // (Ralf:) zomfg, this is one of the worst hacks i've done the last years. Deep within jmdns we // placed a variable to // override a check if it is already safe to transmit something. jmDNS usually takes 5 seconds // to reach that state, but that's // too long for us. If you set this variable the check will be skipped and the request should // take place much faster. // Appears to work(tm). ServiceResolver.ANNOUNCE_OVERRIDE = true; this.logger.status("backgroundinit/start"); final PluginConfigurationUtil pcu = new PluginConfigurationUtil(this.pluginConfiguration); this.startupLock = pcu.getInt(RemoteDiscovery.class, "startup.locktime", 1000); this.lockMode = pcu.getString(RemoteDiscovery.class, "startup.lockmode", "onepass"); try { this.logger.status("backgroundinit/lock"); this.jmdnsLock.lock(); this.jmdns = JmDNS .create(); // Maybe init with local loopback in case no other network card is present, // otherwise returns null this.timeOfStartup = System.currentTimeMillis(); final int port = RemoteDiscoveryImpl.getFreePort(); final ServiceInfo service = ServiceInfo.create(TYPE, NAME + " @" + this.timeOfStartup, port, 0, 0, EXPORT_NAME); this.logger.status("backgroundinit/export", "port", port); this.localManagerExportServer = Proxies.newServer(EXPORT_NAME, port, (DiscoveryManager) this.localTCPIPManager); this.logger.status("backgroundinit/announce", "port", port); this.jmdns.registerService(service); // Set it again, this time for the lock below this.timeOfStartup = System.currentTimeMillis(); } catch (final IOException e) { e.printStackTrace(); } catch (final IllegalStateException e) { this.logger.status("backgroundinit/exception/illegalstate", "message", e.getMessage()); } finally { this.logger.status("backgroundinit/unlock"); this.startupLatch.countDown(); this.jmdnsLock.unlock(); } this.logger.status("backgroundinit/end"); }
/** * Returns the remote proxy to a discovery manager for a given IP / port * * @param ip * @param port * @return */ @SuppressWarnings("unchecked") DiscoveryManager getRemoteProxy(String ip, int port) { try { final String address = ip + ":" + port; final int timeout = 500; // 500 ms RemoteAPIImpl if need detailed // version... final DiscoveryManager newClient = Proxies.newClient( EXPORT_NAME, address, RemoteDiscoveryImpl.class.getClassLoader(), DiscoveryManager.class); /* * TODO: With this one we still get the message: * * "org.freshvanilla.net.VanillaDataSocket allocateBuffer * INFO: DiscoveryManager: Running low on memory, pausing..." * * but, there is no TimeoutException.... * * @sa DiscoveredPluginTest.testMultiplePlugins() */ @SuppressWarnings("unused") int pingRes = newClient.ping(123321); // Execute collection asynchronously (TODO: cache pool usage could be // improved) final ExecutorService cachePool = Executors.newCachedThreadPool(); final ExecutorCompletionService<String> ecs = new ExecutorCompletionService(cachePool); final Future<String> future = ecs.submit( new Callable<String>() { public String call() throws Exception { return AccessController.doPrivileged( new PrivilegedAction<String>() { public String run() { return newClient.toString(); } }); } }); // Wait at most half a second (TODO: Make this configurable) try { final String string = future.get(timeout, TimeUnit.MILLISECONDS); /* * TODO: Probably it is possible to put here some conversion routines... Because it looks like that * only the ExportInfo makes trouble.... Or just make the ExportInfo much better, ie downwards compatible */ if (string == null || newClient.getVersion() != this.localManager.getVersion()) { return null; } return newClient; } catch (final InterruptedException e) { // TODO: This one is not an error anymore. // Interruption is called because we are running cache thread. // System.err // .println("Error while waiting for a getRemoteProxy() result"); // e.printStackTrace(); } catch (final ExecutionException e) { e.printStackTrace(); } catch (final TimeoutException e) { e.printStackTrace(); } catch (final SecurityException e) { e.printStackTrace(); } finally { AccessController.doPrivileged( new PrivilegedAction<Object>() { public Object run() { future.cancel(true); cachePool.shutdownNow(); return null; } }); } return null; } finally { } }
@SuppressWarnings({"unchecked", "boxing", "rawtypes"}) private DiscoveryManager getRemoteProxyToDiscoveryManager(final String ip, final int port) { final String address = ip + ":" + port; final int timeout = 500; // 500 ms RemoteAPIImpl if need detailed version... this.logger.status("remoteproxytodiscovery/start", "ip", ip, "port", port); final DiscoveryManager newClient = Proxies.newClient( EXPORT_NAME, address, getClass().getClassLoader(), DiscoveryManager.class); // Execute collection asynchronously (TODO: cache pool usage could be improved) final ExecutorService cachePool = Executors.newCachedThreadPool(RemoteDiscoveryImpl.threadFactory); final ExecutorCompletionService<String> ecs = new ExecutorCompletionService(cachePool); final Future<String> future = ecs.submit( new Callable<String>() { public String call() throws Exception { return AccessController.doPrivileged( new PrivilegedAction<String>() { public String run() { return newClient.ping(667) == 667 ? "OK" : null; } }); } }); // Wait at most half a second (TODO: Make this configurable) try { final String string = future.get(timeout, TimeUnit.MILLISECONDS); if (string == null) return null; return newClient; } catch (final InterruptedException e) { this.logger.status("remoteproxytodiscovery/exception/interrupted", "message", e.getMessage()); e.printStackTrace(); } catch (final ExecutionException e) { this.logger.status( "remoteproxytodiscovery/exception/executionexception", "message", e.getMessage()); } catch (final TimeoutException e) { this.logger.status( "remoteproxytodiscovery/exception/timeoutexception", "message", e.getMessage()); } catch (final SecurityException e) { this.logger.status( "remoteproxytodiscovery/exception/securityexception", "message", e.getMessage()); e.printStackTrace(); } finally { AccessController.doPrivileged( new PrivilegedAction<Object>() { public Object run() { future.cancel(true); cachePool.shutdownNow(); return null; } }); this.logger.status("remoteproxytodiscovery/end"); } this.logger.status("remoteproxytodiscovery/end"); return null; }