Package org.globus.workspace.client_core.subscribe_tools.internal

Source Code of org.globus.workspace.client_core.subscribe_tools.internal.PollingSubscriptionMasterImpl

/*
* Copyright 1999-2008 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package org.globus.workspace.client_core.subscribe_tools.internal;

import org.globus.workspace.client_core.subscribe_tools.PollingSubscriptionMaster;
import org.globus.workspace.client_core.subscribe_tools.StateChangeListener;
import org.globus.workspace.client_core.subscribe_tools.TerminationListener;
import org.globus.workspace.common.print.Print;
import org.globus.workspace.client_core.repr.Workspace;
import org.globus.workspace.client_core.actions.RPQueryCurrentState;
import org.globus.workspace.client_core.StubConfigurator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis.message.addressing.EndpointReferenceType;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
import edu.emory.mathcs.backport.java.util.concurrent.ScheduledFuture;

import java.util.Hashtable;

public class PollingSubscriptionMasterImpl extends SubscriptionMasterImpl
                                           implements PollingSubscriptionMaster {
   
    // -------------------------------------------------------------------------
    // STATIC VARIABLES
    // -------------------------------------------------------------------------

    private static final Log logger =
            LogFactory.getLog(ListeningSubscriptionMasterImpl.class.getName());

    public static final long DEFAULT_POLL_MS = 2000;
    public static final int DEFAULT_POOL_SIZE = 4;


    // -------------------------------------------------------------------------
    // INSTANCE VARIABLES
    // -------------------------------------------------------------------------

    private final ScheduledThreadPoolExecutor scheduled;
    private final long pollDelayMs;
    private final StubConfigurator stubConf;
   
    // key: AddressIDPair
    // value: FutureTask
    private final Hashtable currentTasks;

   
    // -------------------------------------------------------------------------
    // CONSTRUCTORS
    // -------------------------------------------------------------------------

    public PollingSubscriptionMasterImpl(long pollDelayMilliseconds,
                                         int maxThreads,
                                         StubConfigurator stubConfigurator,
                                         ExecutorService executorService,
                                         Print print) {
        super(executorService, print);
        this.pollDelayMs = pollDelayMilliseconds;
        this.stubConf = stubConfigurator;

        // This is different than executorService, which is what to use for
        // callback task threads.
        // This is for running the poll tasks themselves.
        this.scheduled = new ScheduledThreadPoolExecutor(DEFAULT_POOL_SIZE);

        this.scheduled.setRemoveOnCancelPolicy(true);

        this.scheduled.setMaximumPoolSize(maxThreads);

        this.currentTasks = new Hashtable(8);
    }

    public PollingSubscriptionMasterImpl(long pollDelayMilliseconds,
                                         StubConfigurator stubConfigurator,
                                         ExecutorService executorService,
                                         Print print) {
        this(pollDelayMilliseconds,
             DEFAULT_MAX_POOL_SIZE,
             stubConfigurator,
             executorService,
             print);
    }

    public PollingSubscriptionMasterImpl(StubConfigurator stubConfigurator,
                                         Print print) {
        this(DEFAULT_POLL_MS,
             DEFAULT_MAX_POOL_SIZE,
             stubConfigurator,
             null,
             print);
    }

   
    // -------------------------------------------------------------------------
    // implements PollingSubscriptionMaster
    // -------------------------------------------------------------------------

    public void stopPolling() {
        this.scheduled.shutdownNow();
    }

    public long getPollingMs() {
        return this.pollDelayMs;
    }

    public void setMaxThreads(int maxThreads) {
        if (maxThreads < 1) {
            throw new IllegalArgumentException(
                    "maxThreads may not be less than 1, value: " + maxThreads);
        }
        this.scheduled.setMaximumPoolSize(maxThreads);
    }

    // -------------------------------------------------------------------------
    // overrides SubscriptionMasterImpl
    // -------------------------------------------------------------------------

    public boolean trackStateChanges(Workspace workspace,
                                     StateChangeListener listener) {
        return this.trackCommon(workspace, listener, null);
    }

    public boolean trackTerminationChanges(Workspace workspace,
                                           TerminationListener listener) {
        return this.trackCommon(workspace, null, listener);
    }

    // state changes and termination changes are both tracked via same poll
    private boolean trackCommon(Workspace workspace,
                                StateChangeListener stateListener,
                                TerminationListener terminationListener) {
       
        if (workspace == null) {
            throw new IllegalArgumentException("workspace may not be null");
        }

        if (terminationListener == null && stateListener == null) {
            throw new IllegalArgumentException(
                    "illegal to call with all listeners null");
        }

        if (terminationListener != null && stateListener != null) {
            throw new IllegalArgumentException(
                    "illegal to call with more than one listener non-null");
        }

        synchronized (this.accessLock) {

            final EndpointReferenceType epr = workspace.getEpr();

            // look in the map to see if anything is being tracked already
            final WorkspaceAndListeners wal =
                    this.map.getWorkspace(epr, this.pr);

            // if neither is being tracked yet, start a polling thread
            if (wal == null) {

                final AddressIDPair addrID =
                    WorkspaceMap.chooseAddrID(epr, this.pr);

                final RPQueryCurrentState action =
                        new RPQueryCurrentState(epr, this.stubConf, this.pr);
                action.setStateConduit(this, epr);
                action.setTerminationConduit(this, epr);

                // Can't use FutureTask because of the way scheduleWithFixedDelay
                // will wrap the object.  Results in just one call instead of
                // repeating (thread state gets put into "RAN" in the inner
                // callable.  Instead, made RPQueryCurrentState also implement
                // Runnable interface and so now is native parameter to
                // scheduleWithFixedDelay method instead of wrapped in FutureTask.
                //NOPE: final FutureTask task = new FutureTask(action);

                final ScheduledFuture scheduledFuture =
                        this.scheduled.scheduleWithFixedDelay(
                                action, this.pollDelayMs, this.pollDelayMs,
                                TimeUnit.MILLISECONDS);

                this.currentTasks.put(addrID, scheduledFuture);
            }

            if (terminationListener != null) {
                return super.trackTerminationChanges(workspace,
                                                     terminationListener);
            } else {
                return super.trackStateChanges(workspace,
                                               stateListener);
            }
        }
    }

    public boolean untrackWorkspace(Workspace workspace) {
       
        if (workspace == null) {
            throw new IllegalArgumentException("workspace may not be null");
        }

        synchronized (this.accessLock) {

            final EndpointReferenceType epr = workspace.getEpr();

            final AddressIDPair addrID =
                    WorkspaceMap.chooseAddrID(epr, this.pr);

            if (addrID == null) {
               
                // *** EARLY RETURN ***
                return super.untrackWorkspace(workspace);
            }

            final ScheduledFuture task =
                    (ScheduledFuture) this.currentTasks.get(addrID);
           
            if (task == null) {
                if (this.pr.enabled()) {
                    final String err = "Unexpected: parent tracking this " +
                            "but not the poll subscription manager? " +
                            addrID.toString();
                    if (this.pr.useThis()) {
                        this.pr.errln(err);
                    } else if (this.pr.useLogging()) {
                        logger.error(err);
                    }
                }
                // *** EARLY RETURN ***
                return super.untrackWorkspace(workspace);
            }

            task.cancel(true);
           
            this.currentTasks.remove(addrID);

            return super.untrackWorkspace(workspace);
        }
    }
}
TOP

Related Classes of org.globus.workspace.client_core.subscribe_tools.internal.PollingSubscriptionMasterImpl

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.