public BatchRequestQueue(Instance instance, bool datagram) { Ice.InitializationData initData = instance.initializationData(); _interceptor = initData.batchRequestInterceptor; _batchStreamInUse = false; _batchRequestNum = 0; _batchStream = new BasicStream(instance, Ice.Util.currentProtocolEncoding); _batchStream.writeBlob(Protocol.requestBatchHdr); _batchMarker = _batchStream.size(); _request = new BatchRequestI(this); _maxSize = instance.batchAutoFlushSize(); if(_maxSize > 0 && datagram) { int udpSndSize = initData.properties.getPropertyAsIntWithDefault("Ice.UDP.SndSize", 65535 - _udpOverhead); if(udpSndSize < _maxSize) { _maxSize = udpSndSize; } } }
private void flushRequests() { _m.Lock(); try { Debug.Assert(_connection != null && !_initialized); while(_batchRequestInProgress) { _m.Wait(); } // // We set the _flushing flag to true to prevent any additional queuing. Callers // might block for a little while as the queued requests are being sent but this // shouldn't be an issue as the request sends are non-blocking. // _flushing = true; } finally { _m.Unlock(); } LinkedList<Request> sentCallbacks = new LinkedList<Request>(); try { LinkedListNode<Request> p = _requests.First; // _requests is immutable when _flushing = true while(p != null) { Request request = p.Value; if(request.@out != null) { if(_connection.sendAsyncRequest(request.@out, _compress, _response, out request.sentCallback)) { if(request.sentCallback != null) { sentCallbacks.AddLast(request); } } } else if(request.batchOut != null) { if(_connection.flushAsyncBatchRequests(request.batchOut, out request.sentCallback)) { if(request.sentCallback != null) { sentCallbacks.AddLast(request); } } } else { BasicStream os = new BasicStream(request.os.instance()); _connection.prepareBatchRequest(os); try { request.os.pos(0); os.writeBlob(request.os.readBlob(request.os.size())); } catch(Ice.LocalException) { _connection.abortBatchRequest(); throw; } _connection.finishBatchRequest(os, _compress); } LinkedListNode<Request> tmp = p; p = p.Next; _requests.Remove(tmp); } } catch(LocalExceptionWrapper ex) { _m.Lock(); try { Debug.Assert(_exception == null && _requests.Count > 0); _exception = ex.get(); _reference.getInstance().clientThreadPool().dispatch(delegate() { flushRequestsWithException(ex); }); } finally { _m.Unlock(); } } catch(Ice.LocalException ex) { _m.Lock(); try { Debug.Assert(_exception == null && _requests.Count > 0); _exception = ex; _reference.getInstance().clientThreadPool().dispatch(delegate() { flushRequestsWithException(ex); }); } finally { _m.Unlock(); } } if(sentCallbacks.Count > 0) { Instance instance = _reference.getInstance(); instance.clientThreadPool().dispatch(delegate() { foreach(Request r in sentCallbacks) { if(r.@out != null) { [email protected]__(r.sentCallback); } else if(r.batchOut != null) { r.batchOut.sent__(r.sentCallback); } } }); } // // We've finished sending the queued requests and the request handler now send // the requests over the connection directly. It's time to substitute the // request handler of the proxy with the more efficient connection request // handler which does not have any synchronization. This also breaks the cyclic // reference count with the proxy. // // NOTE: _updateRequestHandler is immutable once _flushing = true // if(_updateRequestHandler && _exception == null) { _proxy.setRequestHandler__(_delegate, new ConnectionRequestHandler(_reference, _connection, _compress)); } _m.Lock(); try { Debug.Assert(!_initialized); if(_exception == null) { _initialized = true; _flushing = false; } _proxy = null; // Break cyclic reference count. _delegate = null; // Break cyclic reference count. _m.NotifyAll(); } finally { _m.Unlock(); } }
// // Marshal the endpoint // public override void streamWrite(BasicStream s) { s.startWriteEncaps(_rawEncoding, Ice.FormatType.DefaultFormat); s.writeBlob(_rawBytes); s.endWriteEncaps(); }
private void flushRequests() { lock(this) { Debug.Assert(_connection != null && !_initialized); while(_batchRequestInProgress) { System.Threading.Monitor.Wait(this); } // // We set the _flushing flag to true to prevent any additional queuing. Callers // might block for a little while as the queued requests are being sent but this // shouldn't be an issue as the request sends are non-blocking. // _flushing = true; } LinkedListNode<Request> p = _requests.First; // _requests is immutable when _flushing = true Ice.LocalException exception = null; while(p != null) { Request request = p.Value; try { if(request.os != null) { BasicStream os = new BasicStream(request.os.instance(), Ice.Util.currentProtocolEncoding); _connection.prepareBatchRequest(os); try { request.os.pos(0); os.writeBlob(request.os.readBlob(request.os.size())); } catch(Ice.LocalException) { _connection.abortBatchRequest(); throw; } _connection.finishBatchRequest(os, _compress); } else if(request.outAsync.send(_connection, _compress, _response, out request.sentCallback)) { if(request.sentCallback != null) { request.outAsync.invokeSentAsync(request.sentCallback); } } } catch(RetryException ex) { exception = ex.get(); try { // Remove the request handler before retrying. _reference.getInstance().requestHandlerFactory().removeRequestHandler(_reference, this); } catch(Ice.CommunicatorDestroyedException) { // Ignore } request.outAsync.retryException(ex.get()); } catch(Ice.LocalException ex) { exception = ex; Ice.AsyncCallback cb = request.outAsync.completed(ex); if(cb != null) { request.outAsync.invokeCompletedAsync(cb); } } LinkedListNode<Request> tmp = p; p = p.Next; _requests.Remove(tmp); } // // If we aren't caching the connection, don't bother creating a // connection request handler. Otherwise, update the proxies // request handler to use the more efficient connection request // handler. // if(_reference.getCacheConnection() && exception == null) { _connectionRequestHandler = new ConnectionRequestHandler(_reference, _connection, _compress); foreach(Ice.ObjectPrxHelperBase prx in _proxies) { prx.setRequestHandler__(this, _connectionRequestHandler); } } lock(this) { Debug.Assert(!_initialized); _exception = exception; _initialized = _exception == null; _flushing = false; try { // // Only remove once all the requests are flushed to // guarantee serialization. // _reference.getInstance().requestHandlerFactory().removeRequestHandler(_reference, this); } catch(Ice.CommunicatorDestroyedException) { // Ignore } _proxies.Clear(); _proxy = null; // Break cyclic reference count. System.Threading.Monitor.PulseAll(this); } }
// // Marshal the endpoint // public override void streamWrite(BasicStream s) { s.writeShort(_type); s.startWriteEncaps(); s.writeBlob(_rawBytes); s.endWriteEncaps(); }