/** When an actual data segment was received; deals with request callbacks if necessary */ private void handleReceivedData(String data) { // deal with any queued callbacks first QueuedRequest request = null; // then check for any requests // (should release lock as soon as possible) synchronized (_lock) { if (_activeRequest != null) { request = _activeRequest; _activeRequest = null; } } if (request != null && request.timeout > 0) { // make sure it hasn't been too long i.e. timeout if (request.isExpired()) { _logger.debug("Active request has expired"); // fire the timeout handler _callbackHandler.handle(_timeoutCallback, _callbackErrorHandler); } else { // fire the response request's response handler request.setResponse(data); _callbackHandler.handle(request.responseHandler, data, _callbackErrorHandler); } } // ...then fire the 'received' callback next _callbackHandler.handle(_receivedCallback, data, _callbackErrorHandler); processQueue(); }
public void doQueueRequest(QueuedRequest request) { // whether or not this entry had to be queued boolean queued = false; synchronized (_lock) { if (_activeRequest == null) { _logger.debug("Active request made. data:[{}]", request.request); // make it the active request and don't queue it _activeRequest = request; // will be sent next, so start timing _activeRequest.startTimeout(); } else { _logger.debug("Queued a request. data:[{}]", request.request); // a request is active, so queue this new one _requestQueue.add(request); _queueLength++; queued = true; } } if (!queued && request.requestBuffer != null) { sendBufferNow(request.requestBuffer, request.request, true); } // without a timer, the queue needs to serviced on both send and receive processQueue(); }
/** Expires and initiates requests in the queue (assumes not synced) */ private void processQueue() { // if any new requests are found QueuedRequest nextRequest = null; // if a timeout callback needs to be fired boolean callTimeout = false; synchronized (_lock) { // check if any active requests need expiring if (_activeRequest != null) { if (_activeRequest.responseHandler == null || _activeRequest.timeout <= 0) { // was a blind request or _activeRequest = null; } else if (_activeRequest.isExpired()) { _logger.debug("Active request has expired"); // timeout callback must be fired callTimeout = true; // clear active request _activeRequest = null; } else if (_activeRequest.isLongTermExpired()) { _logger.debug("Active request has long term expired"); callTimeout = true; _activeRequest = null; } else { // there is still an valid active request, // so just get out of here return; } } } // call the timeout callback, (there's an opportunity for request queue to be cleared by // callback handler) if (callTimeout) _callbackHandler.handle(_timeoutCallback, _callbackErrorHandler); // an active request might have come in synchronized (_lock) { if (_activeRequest != null) { // there's an active request, so leave it to play out return; } // record this for logging int longTermDropped = 0; try { for (; ; ) { // no active request, check for queued ones nextRequest = _requestQueue.poll(); if (nextRequest == null) { // no more requests either, so nothing more to do _logger.debug("No new requests in queue."); return; } _queueLength--; if (!nextRequest.isLongTermExpired()) break; // otherwise, continue to expire the long term queued longTermDropped++; } } finally { if (longTermDropped > 0) _logger.debug("(dropped {} long term queued requests.)", longTermDropped); } // set active request and start timeout *before* sending _activeRequest = nextRequest; nextRequest.startTimeout(); } // if the request has send data 'data' send now if (nextRequest.requestBuffer != null) sendBufferNow(nextRequest.requestBuffer, nextRequest.request, false); }