/** {@inheritDoc} */ @Override public void setBroadcasterLifeCyclePolicy(final BroadcasterLifeCyclePolicy lifeCyclePolicy) { this.lifeCyclePolicy = lifeCyclePolicy; if (currentLifecycleTask != null) { currentLifecycleTask.cancel(false); } if (lifeCyclePolicy.getLifeCyclePolicy() == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE || lifeCyclePolicy.getLifeCyclePolicy() == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE_DESTROY) { int time = lifeCyclePolicy.getTimeout(); if (time == -1) { throw new IllegalStateException("BroadcasterLifeCyclePolicy time is not set"); } final AtomicReference<Future<?>> ref = new AtomicReference<Future<?>>(); currentLifecycleTask = bc.getScheduledExecutorService() .scheduleAtFixedRate( new Runnable() { @Override public void run() { try { if (resources.isEmpty()) { notifyEmptyListener(); notifyIdleListener(); if (lifeCyclePolicy.getLifeCyclePolicy() == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE) { releaseExternalResources(); logger.debug("Applying BroadcasterLifeCyclePolicy IDLE policy"); } else { notifyDestroyListener(); destroy(); /** * The value may be null if the timeout is too low. Hopefully next * execution will cancel the task properly. */ if (ref.get() != null) { currentLifecycleTask.cancel(true); } logger.debug("Applying BroadcasterLifeCyclePolicy IDLE_DESTROY policy"); } } } catch (Throwable t) { logger.warn("Scheduled BroadcasterLifeCyclePolicy exception", t); } } }, time, time, lifeCyclePolicy.getTimeUnit()); ref.set(currentLifecycleTask); } }
/** {@inheritDoc} */ public <T> Future<T> delayBroadcast(final T o, long delay, TimeUnit t) { if (destroyed.get()) throw new IllegalStateException("This Broadcaster has been destroyed and cannot be used"); start(); final Object msg = filter(o); if (msg == null) return null; final BroadcasterFuture<Object> future = new BroadcasterFuture<Object>(msg); final Entry e = new Entry(msg, null, future, o); Future<T> f; if (delay > 0) { f = bc.getScheduledExecutorService() .schedule( new Callable<T>() { public T call() throws Exception { delayedBroadcast.remove(e); if (Callable.class.isAssignableFrom(o.getClass())) { try { Object r = Callable.class.cast(o).call(); final Object msg = filter(r); if (msg != null) { Entry entry = new Entry(msg, null, null, r); push(entry); } return (T) msg; } catch (Exception e1) { logger.error("", e); } } final Object msg = filter(o); final Entry e = new Entry(msg, null, null, o); push(e); return (T) msg; } }, delay, t); e.future = new BroadcasterFuture<Object>(f, msg); } delayedBroadcast.offer(e); return future; }
/** {@inheritDoc} */ public Future<?> scheduleFixedBroadcast(final Object o, long waitFor, long period, TimeUnit t) { if (destroyed.get()) throw new IllegalStateException("This Broadcaster has been destroyed and cannot be used"); start(); if (period == 0 || t == null) { return null; } final Object msg = filter(o); if (msg == null) return null; return bc.getScheduledExecutorService() .scheduleWithFixedDelay( new Runnable() { public void run() { if (Callable.class.isAssignableFrom(o.getClass())) { try { Object r = Callable.class.cast(o).call(); final Object msg = filter(r); if (msg != null) { Entry entry = new Entry(msg, null, null, r); push(entry); } return; } catch (Exception e) { logger.error("", e); } } final Object msg = filter(o); final Entry e = new Entry(msg, null, null, o); push(e); } }, waitFor, period, t); }