private void abandonNow(ClientConnection abandonded) { Pipe<NetPayloadSchema> pipe = output[abandonded.getResponsePipeIdx()]; ///ensure that this will not cause any stall, better to skip this than be blocked. if (Pipe.hasRoomForWrite(pipe)) { long nowNS = System.nanoTime(); long callTime = abandonded.outstandingCallTime(nowNS); logger.warn("\nClient disconnected {} con:{} session:{} because call was taking too long. Estimated:{}", abandonded, abandonded.id, abandonded.sessionId,Appendables.appendNearestTimeUnit(new StringBuilder(), callTime)); abandonded.touchSentTime(nowNS);//rest the timeout so we do not attempt to close this again until the timeout has passed again. if (!abandonded.isDisconnecting()) { abandonded.beginDisconnect(); } int size = Pipe.addMsgIdx(pipe, NetPayloadSchema.MSG_DISCONNECT_203); Pipe.addLongValue(abandonded.getId(), pipe); Pipe.confirmLowLevelWrite(pipe, size); Pipe.publishWrites(pipe); //Do not set notification sent this message will trigger that one later once it makes it down the pipe. } }
long callTime = t.outstandingCallTime(scanTime); +" isValid:"+t.isValid+" isReg:"+t.isRegistered()+" isDis:"+t.isDisconnecting +" sentClosedNotice:"+t.isClientClosedNotificationSent() ); if ((!t.isClientClosedNotificationSent()) && t.isRegistered()) { if (t.isDisconnecting || !t.isValid) {//do not kill those starting up. if (callTime>CLOSED_LINGER_NS) { if (ElapsedTimeRecorder.totalCount(t.histogram())>100) { RunningStdDev.sample(stdDev, ElapsedTimeRecorder.elapsedAtPercentile(t.histogram(), .98)); long timeout = t.getTimeoutNS(); if (timeout>0) {//overrides general behavior if set if (callTime>timeout) {
if (cc.isValid() && !cc.isDisconnecting()) { cc.recordArrivalTime(temp); cc.close();
private boolean connectionIsBad() { //only check once out of every 16 calls since this is expensive if (0 == (0xF&badConnectionCounter++)) { return (!activeConnection.isValid()) && activeConnection.isFinishConnect(); } else { return false;//assumed to be ok } }
@Override public void dispose(ClientConnection connection) { //we MUST open a new connection so we kill the oldest now. //logger.info("CLIENT SIDE BEGIN CONNECTION CLOSE"); connection.beginDisconnect(); //TODO: should we build a blocking write OR always keep some free. //connection.handShakeWrapIfNeeded(cc, target, buffer) connection.close(); if (true) { throw new UnsupportedOperationException("Can not close old connection without finishing handshake."); } }
public void registerForUse(Selector selector, Pipe<NetPayloadSchema>[] handshakeBegin, boolean isTLS) throws IOException { SocketChannel socket = getSocketChannel(); assert(null==socket || socket.finishConnect()); if (null==socket) { return;//not valid; } //logger.trace("now finished connection to : {} ",getSocketChannel().getRemoteAddress().toString()); //logger.info("is now valid connection {} ",this.id); SelectionKey tempkey = getSocketChannel().register(selector, SelectionKey.OP_READ, this); if (isTLS) { beginHandshakeNow(handshakeBegin); } isValid = true; //must be last, this connection can not be used until this key is not null; this.key = tempkey; }
|| (!cc.isValid()) //was closed with notification or not yet open || cc.isDisconnecting() //was closed without notification and we need to establish a new socket || cc.isClientClosedNotificationSent() ) { if((null!=cc) && (!cc.isClientClosedNotificationSent())) { return null;//do not replace until notification sent ClientConnection old = ccm.connections.setValue(originalId, cc); if (null!=old) { old.close(); old.decompose(); old2.close(); old2.decompose(); if (cc.isDisconnecting()) { return cc; if (cc.isRegistered()) {
private boolean connectionStateChecks(Pipe<ClientHTTPRequestSchema> requestPipe) { if (null != activeConnection) { assert(activeConnection.isFinishConnect()); HandshakeStatus handshakeStatus = activeConnection.getEngine().getHandshakeStatus(); if (needsToShake(handshakeStatus)) { long usageCount = ElapsedTimeRecorder.totalCount(activeConnection.histogram()); if (0==usageCount) { activeConnection.clientClosedNotificationSent(); activeConnection.close(); //close so next call we will get a fresh connection activeConnection.close(); activeConnection = null; if (activeConnection.isBusy() || !Pipe.hasRoomForWrite(output[activeConnection.requestPipeLineIdx()])) { return false;//must try again later when the server has responded.
System.out.println("Con: "+conObjPrev.id+" registered:"+conObjPrev.isRegistered()+" valid:"+conObjPrev.isValid()+" Outstanding:" + Appendables.appendNearestTimeUnit(new StringBuilder(), conObjPrev.outstandingCallTime(System.nanoTime()))+" atIdx: "+prevConnectionId + " closedNoticeSent:"+conObjPrev.isClientClosedNotificationSent() );
private void publishCloseAsNeeded(final int stateIdx, ClientConnection cc, int i) { final int dest = cc.getResponsePipeIdx(); cc.clearPoolReservation(); if (!cc.isClientClosedNotificationSent()) { if (!cc.isDisconnecting()) { cc.beginDisconnect();//must be marked as disconnecting so it get re-connected if requests start up again. cc.clientClosedNotificationSent();
private void beginHandshakeNow(Pipe<NetPayloadSchema>[] handshakeBegin) throws SSLException { getEngine().beginHandshake(); logger.trace("\nbegin handshake for : {} pipes:{} ",getId(),handshakeBegin.length); HandshakeStatus handshake = getEngine().getHandshakeStatus(); while (HandshakeStatus.NEED_TASK == handshake) { Runnable task; while ((task = getEngine().getDelegatedTask()) != null) { task.run(); handshake = getEngine().getHandshakeStatus(); do { final Pipe<NetPayloadSchema> pipe = handshakeBegin[requestPipeLineIdx()]; assert(null!=pipe); Pipe.addLongValue(getId(), pipe); Pipe.addLongValue(System.currentTimeMillis(), pipe); Pipe.addLongValue(SSLUtil.HANDSHAKE_POS, pipe);
private boolean tryWrite(int i) { ClientConnection cc = connections[i]; ByteBuffer mappedByteBuffer = buffers[i]; if (cc!=null && cc.isValid() && !cc.isDisconnecting()) { SocketChannel sc = cc.getSocketChannel(); if (sc!=null) { if (connections[i].getSocketChannel().write(mappedByteBuffer)<=0) { break;//can't write now, try later. }; connections[i].close(); connections[i]=null; ((Buffer)mappedByteBuffer).clear();
activeConnection.close(); if (null==clientConnection || (! clientConnection.isFinishConnect())) { break; Pipe<NetPayloadSchema> server = toBroker[activeConnection.requestPipeLineIdx()]; if (HandshakeStatus.NEED_UNWRAP == clientConnection.getEngine().getHandshakeStatus()) { return;//wait until this is cleared before continuing assert(Pipe.isForSchema(toBroker[activeConnection.requestPipeLineIdx()], NetPayloadSchema.instance)) : "found unexpected "+Pipe.schemaName(toBroker[activeConnection.requestPipeLineIdx()]);
int useUsersPipe = connection.requestPipeLineIdx(); //this lets us return to the same pipe we registered with long connectionId = connection.getId(); if (!sendSingleMessage(pipe[useUsersPipe], connectionId, testSeeds[testIdx], testSizes[testIdx])){ return;//try again later
try { SocketChannel socketChannel = getSocketChannel(); if (socketChannel!=null) { boolean finishConnect = socketChannel.finishConnect(); beginDisconnect(); clearWaitingForNetwork(); if (showConectionDetails) { logger.info("new connection completed to {}:{}",host,port); close(); isFinishedConnection = true; close(); if (showConectionDetails) { logger.info("finish connection exception ",io); close(); if (showConectionDetails) { logger.info("no pending connection ",ncpe);
@Override public boolean isValid(ClientConnection connection) { return null!=connection && connection.isValid(); }
private boolean hasRoomForNewMessagePlusReplay() { Pipe<NetPayloadSchema> server = toBroker[activeConnection.requestPipeLineIdx()];
SocketChannel socketChannel = (SocketChannel)cc.getSocketChannel(); if (null != socketChannel) { try { writePlain(cc, target, readCount); } else { writeEncrypted(cc.getId(), target, readCount);
public static void cleanCloseConnection(Pipe<ClientHTTPRequestSchema> requestPipe, ClientConnection connectionToKill, Pipe<NetPayloadSchema> pipe) { //must consume each field so we can move forward, this is required or the position will be off... //matches ClientHTTPRequestSchema.MSG_CLOSECONNECTION_104 int session = Pipe.takeInt(requestPipe); int port = Pipe.takeInt(requestPipe); int hostId = Pipe.takeInt(requestPipe); long conId = Pipe.takeLong(requestPipe); //do not close that will be done by last stage //must be done first before we send the message connectionToKill.beginDisconnect(); Pipe.presumeRoomForWrite(pipe); int size = Pipe.addMsgIdx(pipe, NetPayloadSchema.MSG_DISCONNECT_203); Pipe.addLongValue(connectionToKill.getId(), pipe);// NetPayloadSchema.MSG_DISCONNECT_203_FIELD_CONNECTIONID_201, connectionToKill.getId()); Pipe.confirmLowLevelWrite(pipe, size); Pipe.publishWrites(pipe); }
cc.recordSentTime(System.nanoTime()); logger.info("/////\n/// has connection "+((cc!=null)&&cc.isValid())+" channelId "+channelId+" write encrypted length:"+len2); cc.recordSentTime(System.nanoTime()); latencyRecordings[i] = cc!=null?cc.histogram():null;//keep for later didWork |= tryWrite(i); return didWork;