All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Alachisoft.NCache.Common.Communication.RequestManager Maven / Gradle / Ivy

package Alachisoft.NCache.Common.Communication;

import Alachisoft.NCache.Common.Communication.Exceptions.ChannelException;
import Alachisoft.NCache.Common.Exceptions.TimeoutException;
import Alachisoft.NCache.Common.IDisposable;
import Alachisoft.NCache.Common.Threading.Monitor;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;

public class RequestManager implements IChannelEventListener, IDisposable {

    private IChannel _channel;
    private java.util.HashMap _requests = new java.util.HashMap();
    private Object _lock = new Object();
    private long _lastRequestId;
    private boolean _resendRequestOnChannelDisconnect = true;
    private int _requestTimeout = 90 * 1000; //default is ninety second

    public RequestManager(IChannel chnnel) {
        if (chnnel == null) {
            throw new IllegalArgumentException("Value cannot be null."+System.lineSeparator()+"Parameter name: channel");
        }

        _channel = chnnel;
        _channel.RegisterEventListener(this);
    }

    public final int getRequestTimedout() {
        return _requestTimeout;
    }

    public final void setRequestTimedout(int value) {
        _requestTimeout = value;
    }

    public final boolean getIsConnected()
    {
        return _channel != null ? _channel.getIsConnected() : false;
    }

    public final Object SendRequest(IRequest request) throws TimeoutException, UnsupportedEncodingException, InterruptedException {
        Object response = null;

        request.setRequestId(GenerateRequestId());
        RequestResponsePair reqRespPair = new RequestResponsePair();

        synchronized (_lock) {
            reqRespPair.setRequest(request);

            if (!_requests.containsKey(request.getRequestId())) {
                _requests.put(request.getRequestId(), reqRespPair);
            }
        }

        synchronized (reqRespPair) {
            try {
               if(_channel !=null)
                    _channel.SendMessage(request);
                reqRespPair.setRequestSentOverChannel(true);
                //lockReacquired = System.Threading.Monitor.Wait(reqRespPair);
                Monitor.wait(reqRespPair, _requestTimeout); //reqRespPair.wait();
            } catch (ChannelException e) {
                throw e;
            } finally {
                synchronized (_lock) {
                    _requests.remove(request.getRequestId());
                }
            }
        }

        if (!reqRespPair.getLockAccquired()) {
            throw new TimeoutException();
        }
        reqRespPair.setLockAccquired(false);

        if (reqRespPair.getChannelException() != null) {
            throw reqRespPair.getChannelException();
        }

        response = reqRespPair.getResponse();

        return response;
    }

    private long GenerateRequestId() {
        synchronized (this) {
            long requestId = ++_lastRequestId;
            if (requestId < 0) {
                _lastRequestId = 0;
                requestId = 0;
            }
            return requestId;
        }
    }

    public final void ReceiveResponse(IResponse response) {
        IResponse protoResponse = response;
        RequestResponsePair reqResponsePair = (RequestResponsePair) ((_requests.get(protoResponse.getRequestId()) instanceof RequestResponsePair) ? _requests.get(protoResponse.getRequestId()) : null);

        synchronized (reqResponsePair) {

            if (reqResponsePair != null) {
                reqResponsePair.setResponse(protoResponse);
                //System.Threading.Monitor.Pulse(reqResponsePair);
                reqResponsePair.setLockAccquired(true);
                Monitor.pulse(reqResponsePair); //reqResponsePair.notifyAll();
            }

        }
    }

    public final void ChannelDisconnected(String reason) throws UnsupportedEncodingException {
        synchronized (_lock) {
            Object tempVar = _requests.clone();
            java.util.HashMap requestClone = (java.util.HashMap) ((tempVar instanceof java.util.HashMap) ? tempVar : null);
            Iterator ide = requestClone.entrySet().iterator();

            while (ide.hasNext()) {
                Map.Entry current = (Map.Entry) ide.next();
                RequestResponsePair reqRspPair = (RequestResponsePair) ((current.getValue() instanceof RequestResponsePair) ? current.getValue() : null);

                if (!reqRspPair.getRequestSentOverChannel()) {
                    continue;
                }

                synchronized (reqRspPair) {
                    if (_resendRequestOnChannelDisconnect) {
                        //resend the request when channel is disconnected
                        try {
                            if (_channel != null) {
                                _channel.SendMessage(reqRspPair.getRequest());
                            }
                        } catch (ChannelException ce) {
                            reqRspPair.setChannelException(ce);
                            Monitor.pulse(reqRspPair);// reqRspPair.notifyAll();
                            //System.Threading.Monitor.PulseAll(reqRspPair);
                        }
                    } else {
                        reqRspPair.setChannelException(new ChannelException(reason));
                        //System.Threading.Monitor.PulseAll(reqRspPair);
                        Monitor.pulse(reqRspPair);//reqRspPair.notifyAll();
                    }
                }
            }
        }
    }

    public final void dispose() {
        try {
            synchronized (_lock) {
                _requests.clear();
            }

            if (_channel != null) {
                _channel.Disconnect();
                _channel = null;
            }

        } catch (Exception e) {
        }
    }

    protected void finalize() throws Throwable {
        dispose();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy