Package com.ponysdk.core.concurrent

Source Code of com.ponysdk.core.concurrent.UIScheduledThreadPoolExecutor$UIRunnable

package com.ponysdk.core.concurrent;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

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

import com.ponysdk.core.UIContext;
import com.ponysdk.core.UIContextListener;
import com.ponysdk.ui.server.basic.PWindow;

public class UIScheduledThreadPoolExecutor implements UIScheduledExecutorService, UIContextListener {

    private static Logger log = LoggerFactory.getLogger(UIScheduledThreadPoolExecutor.class);

    private static UIScheduledThreadPoolExecutor INSTANCE;

    protected final ScheduledThreadPoolExecutor executor;
    protected Map<UIContext, Set<UIRunnable>> runnablesByUIContexts = new ConcurrentHashMap<UIContext, Set<UIRunnable>>();

    private UIScheduledThreadPoolExecutor(final ScheduledThreadPoolExecutor executor) {
        log.info("Initializing UIScheduledThreadPoolExecutor");
        this.executor = executor;
    }

    public static UIScheduledThreadPoolExecutor initDefault() {
        if (INSTANCE != null) throw new IllegalAccessError("Already initialized");
        INSTANCE = new UIScheduledThreadPoolExecutor(new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors()));
        return INSTANCE;
    }

    public static UIScheduledThreadPoolExecutor init(final ScheduledThreadPoolExecutor executor) {
        if (INSTANCE != null) throw new IllegalAccessError("Already initialized");
        INSTANCE = new UIScheduledThreadPoolExecutor(executor);
        return INSTANCE;
    }

    public static UIScheduledThreadPoolExecutor get() {
        return INSTANCE;
    }

    private void checkUIState() {
        if (UIContext.get() == null) throw new IllegalAccessError("UIScheduledThreadPoolExecutor must be called from UI client code");
        if (UIContext.get().getPusher() == null) throw new IllegalAccessError("PPusher not initialized");
    }

    @Override
    public ScheduledFuture<?> schedule(final Runnable command, final long delay, final TimeUnit unit) {
        checkUIState();
        final UIRunnable runnable = new UIRunnable(command);
        final ScheduledFuture<?> future = executor.schedule(runnable, delay, unit);
        runnable.setFuture(future);
        registerTask(runnable);

        return future;
    }

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(final Runnable command, final long initialDelay, final long period, final TimeUnit unit) {
        checkUIState();
        final UIRunnable runnable = new UIRunnable(command);
        final ScheduledFuture<?> future = executor.scheduleAtFixedRate(runnable, initialDelay, period, unit);
        runnable.setFuture(future);
        registerTask(runnable);

        return future;
    }

    @Override
    public ScheduledFuture<?> scheduleWithFixedDelay(final Runnable command, final long initialDelay, final long delay, final TimeUnit unit) {
        checkUIState();

        final UIRunnable runnable = new UIRunnable(command);
        final ScheduledFuture<?> future = executor.scheduleWithFixedDelay(runnable, initialDelay, delay, unit);
        runnable.setFuture(future);
        registerTask(runnable);

        return future;
    }

    static class WindowUIRunnable implements Runnable {

        private final Runnable runnable;
        private final PWindow window;

        public WindowUIRunnable(final PWindow window, final Runnable runnable) {
            this.runnable = runnable;
            this.window = window;
        }

        @Override
        public void run() {
            window.acquire();
            try {
                runnable.run();
                window.flush();
            } catch (final Exception e) {
                log.error("Cannot run UIRunnable", e);
            } finally {
                window.release();
            }
        }
    }

    protected class UIRunnable implements Runnable {

        private final Runnable runnable;
        private final UIContext uiContext;

        private boolean cancelled;
        private ScheduledFuture<?> future;
        private final PWindow window;

        public UIRunnable(final Runnable runnable) {
            this.uiContext = UIContext.get();

            this.window = UIContext.getCurrentWindow();
            if (window != null) {
                this.runnable = new WindowUIRunnable(window, runnable);
            } else {
                this.runnable = runnable;
            }
        }

        @Override
        public void run() {
            if (cancelled) return;
            if (!uiContext.getPusher().execute(runnable)) cancel();
        }

        public void cancel() {
            this.cancelled = true;
            this.future.cancel(true);
            executor.purge();
        }

        public void setFuture(final ScheduledFuture<?> future) {
            this.future = future;
        }

        public UIContext getUiContext() {
            return uiContext;
        }

    }

    protected void registerTask(final UIRunnable runnable) {
        final UIContext uiContext = runnable.getUiContext();
        uiContext.addUIContextListener(this);
        Set<UIRunnable> runnables = runnablesByUIContexts.get(uiContext);
        if (runnables == null) {
            runnables = new HashSet<UIScheduledThreadPoolExecutor.UIRunnable>();
            runnablesByUIContexts.put(uiContext, runnables);
        }
        runnables.add(runnable);
    }

    @Override
    public void onUIContextDestroyed(final UIContext uiContext) {
        final Set<UIRunnable> runnables = runnablesByUIContexts.remove(uiContext);
        if (runnables != null) {
            for (final UIRunnable runnable : runnables) {
                runnable.cancel();
            }
        }
    }

}
TOP

Related Classes of com.ponysdk.core.concurrent.UIScheduledThreadPoolExecutor$UIRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.