Package xbird.engine

Source Code of xbird.engine.RequestManager

/*
* @(#)$Id: RequestManager.java 3624 2008-03-26 08:01:20Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* 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.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.engine;

import java.io.Serializable;
import java.rmi.RemoteException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import xbird.engine.Request.ReplyPattern;
import xbird.engine.sched.Scheduler;
import xbird.engine.sched.SchedulerFactory;
import xbird.util.cache.Cache;
import xbird.util.cache.CacheException;
import xbird.util.cache.CacheFactory;

/**
* The Dispatcher/Manager of various requests.
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
*/
public final class RequestManager implements ResponseListener {
    private static final Log LOG = LogFactory.getLog(RequestManager.class);

    private final Scheduler _sched;
    private final Cache<String, Serializable> _pendingPolled;

    @SuppressWarnings("unchecked")
    public RequestManager() {
        this._sched = SchedulerFactory.createScheduler(this);
        this._pendingPolled = CacheFactory.createCache(RequestManager.class.getName());
    }

    public Serializable dispatchRequest(Request request) throws RemoteException {
        // schedule task
        RequestContext rc = new RequestContext(request);
        _sched.addTask(rc);

        // execute task
        final Serializable result;
        ReplyPattern replyPtn = request.getReplyPattern();
        if(replyPtn == ReplyPattern.RESPONSE) {// synchronous response
            Serializable promptResult = rc.getResult();
            if(promptResult != null) {
                result = promptResult;
            } else {
                syncSignal(true, rc);
                result = rc.getResult();
            }
            if(result == null) {
                Throwable fault = rc.getFault();
                if(fault != null) {
                    throw new RemoteException("Request# " + request.getIdentifier() + " failed.\n"
                            + rc.printableStatus(), fault);
                }
                long timeout = request.getTimeout();
                if(timeout != Request.NO_TIMEOUT) {
                    String timeoutMsg = "Request# " + request.getIdentifier()
                            + " has been timeout since the request took over " + timeout / 1000
                            + " seconds";
                    LOG.warn(timeoutMsg);
                    throw new RemoteException(timeoutMsg);
                }
                LOG.warn("null result for Request#" + request.getIdentifier());
            }
        } else {// asynchronous response
            result = null;
        }
        if(LOG.isInfoEnabled()) {
            LOG.info(rc.printableStatus());
        }
        return result;
    }

    /** handle the responding callback of the task */
    public void onResponse(RequestContext rc) throws RemoteException {
        rc.setFinished(System.currentTimeMillis());
        syncSignal(false, rc);

        Request request = rc.getRequest();
        ReplyPattern type = request.getReplyPattern();
        if(type == ReplyPattern.CALLBACK) {
            ResultHandler handler = request.getResultHandler();
            if(handler == null) {
                throw new IllegalStateException("ResultHandler is not set for the Callback reply pattern on Request#"
                        + request.getIdentifier());
            }
            Serializable result = rc.getResult();
            if(result == null) {
                Throwable fault = rc.getFault();
                if(fault != null) {
                    handler.handleError(request, fault);
                    return;
                }
                long timeout = request.getTimeout();
                if(timeout != Request.NO_TIMEOUT) {
                    String timeoutMsg = "Request# " + request.getIdentifier()
                            + " has been timeout since the request took over " + timeout / 1000
                            + " seconds";
                    LOG.warn(timeoutMsg);
                    handler.handleError(request, timeoutMsg);
                    return;
                }
                LOG.warn("null result for Request#" + request.getIdentifier());
            }
            handler.handleResult(result);
        } else if(type == ReplyPattern.POLL) {
            String rid = request.getIdentifier();
            Serializable result = rc.getResult();
            try {
                _pendingPolled.put(rid, result);
            } catch (CacheException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    public Object pollRequest(Request request) {
        final String rid = request.getIdentifier();
        final Object result;
        try {
            result = _pendingPolled.get(rid);
            if(result != null) {
                _pendingPolled.remove(rid);
            }
        } catch (CacheException e) {
            throw new IllegalStateException(e);
        }
        return result;
    }

    protected final void syncSignal(final boolean pause, final RequestContext rctxt) {
        if(pause) {
            final long timeout = rctxt.getRequest().getTimeout();
            try {
                synchronized(rctxt) {
                    if(rctxt.isNotified()) {
                        return;
                    }
                    if(timeout != Request.NO_TIMEOUT) {
                        rctxt.wait(timeout);
                    } else {
                        rctxt.wait();
                    }
                }
            } catch (InterruptedException e) {
                LOG.warn("could not acquire a thread lock", e);
            }
        } else {
            synchronized(rctxt) {
                rctxt.invokeNotify();
            }
        }
    }

}
TOP

Related Classes of xbird.engine.RequestManager

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.