/** * This is used to listen for a notification from the reactor to * tell the thread that the write operation has completed. If * the thread is interrupted upon this call then this will throw * an <code>IOException</code> with the root cause. */ private void listen() throws IOException { try { if(!closed) { trace.trace(WRITE_BLOCKING); lock.wait(120000); } } catch(Exception e) { throw new TransportException("Schedule error", e); } if(closed) { throw new TransportException("Socket closed"); } }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This is used to flush the internal buffer to the underlying * socket. Flushing with this method is always non-blocking, so * if the socket is not write ready and the buffer can be queued * it will be queued and the calling thread will return. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } writer.flush(); }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This is used to flush the internal buffer to the underlying * socket. Flushing with this method is always non-blocking, so * if the socket is not write ready and the buffer can be queued * it will be queued and the calling thread will return. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } writer.flush(); }
/** * This method is used to deliver the provided buffer of bytes to * the underlying transport. Depending on the connection type the * array may be encoded for SSL transport or send directly. This * will buffer the bytes within the internal buffer to ensure * that the response fragments are sufficiently large for the * network. Smaller packets result poorer performance. * * @param data this is the array of bytes to send to the client */ public void write(ByteBuffer data) throws IOException{ if(closed) { throw new TransportException("Transport is closed"); } writer.write(data); }
/** * This method is used to deliver the provided buffer of bytes to * the underlying transport. Depending on the connection type the * array may be encoded for SSL transport or send directly. This * will buffer the bytes within the internal buffer to ensure * that the response fragments are sufficiently large for the * network. Smaller packets result poorer performance. * * @param data this is the array of bytes to send to the client */ public void write(ByteBuffer data) throws IOException{ if(closed) { throw new TransportException("Transport is closed"); } writer.write(data); }
/** * Here in this method we schedule a flush when the underlying * writer is write ready. This allows the writer thread to return * without having to fully flush the content to the underlying * transport. If there are references queued this will block. */ public synchronized void flush() throws IOException { if(closed) { throw new TransportException("Flusher is closed"); } boolean block = writer.isBlocking(); if(!closed) { scheduler.schedule(block); } }
/** * To ensure that we can release any references and thus avoid a * blocking thread this method will attempt to merge references * in to the internal buffer. Compacting in this manner is done * only if the full reference can fit in to the available space. */ private synchronized void compact() throws IOException { if(closed) { throw new TransportException("Buffer has been closed"); } if(reference != null) { int remaining = reference.remaining(); int space = appender.space(); if(remaining < space) { appender.append(reference); // try to release the buffer reference = null; } } }
/** * To ensure that we can release any references and thus avoid a * blocking thread this method will attempt to merge references * in to the internal buffer. Compacting in this manner is done * only if the full reference can fit in to the available space. */ private synchronized void compact() throws IOException { if(closed) { throw new TransportException("Buffer has been closed"); } if(reference != null) { int remaining = reference.remaining(); int space = appender.space(); if(remaining < space) { appender.append(reference); // try to release the buffer reference = null; } } }
/** * This is used to repeat schedule the operation for execution. * This is executed if the operation has not fully completed * its task. If the scheduler is not in a running state then * this will not schedule the task for a repeat execution. */ public void repeat() throws IOException { if(closed) { throw new TransportException("Socket closed"); } if(running) { trace.trace(WRITE_WAIT); reactor.process(task, OP_WRITE); } }
/** * This is used to repeat schedule the operation for execution. * This is executed if the operation has not fully completed * its task. If the scheduler is not in a running state then * this will not schedule the task for a repeat execution. */ public void repeat() throws IOException { if(closed) { throw new TransportException("Socket closed"); } if(running) { trace.trace(WRITE_WAIT); reactor.process(task, OP_WRITE); } }
/** * Here in this method we schedule a flush when the underlying * writer is write ready. This allows the writer thread to return * without having to fully flush the content to the underlying * transport. If there are references queued this will block. */ public synchronized void flush() throws IOException { if(closed) { throw new TransportException("Flusher is closed"); } boolean block = !buffer.ready(); if(!closed) { scheduler.schedule(block); } }
/** * This is used to flush the internal buffer to the underlying * socket. Flushing with this method is always non-blocking, so * if the socket is not write ready and the buffer can be queued * it will be queued and the calling thread will return. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } Packet packet = builder.build(); if(packet != null) { writer.write(packet); } }
/** * This is used to repeat schedule the operation for execution. * This is executed if the operation has not fully completed * its task. If the scheduler is not in a running state then * this will not schedule the task for a repeat execution. */ public void repeat() throws IOException { if(closed) { throw new TransportException("Socket closed"); } if(running) { trace.trace(WRITE_WAIT); reactor.process(task, OP_WRITE); } }
/** * Here in this method we schedule a flush when the underlying * writer is write ready. This allows the writer thread to return * without having to fully flush the content to the underlying * transport. If there are references queued this will block. */ public synchronized void flush() throws IOException { if(closed) { throw new TransportException("Flusher is closed"); } boolean block = !buffer.ready(); if(!closed) { scheduler.schedule(block); } }
/** * This is used to schedule the task for execution. If this is * given a boolean true to indicate that it wishes to block * then this will block the calling thread until such time as * the <code>ready</code> method is invoked. * * @param block indicates whether the thread should block */ public void schedule(boolean block) throws IOException { if(closed) { throw new TransportException("Socket closed"); } if(!running) { trace.trace(WRITE_WAIT); reactor.process(task, OP_WRITE); running = true; } if(block) { listen(); } }
/** * This method is used to stop the <code>Selector</code> so that * all resources are released. As well as freeing occupied memory * this will also stop all threads, which means that is can no * longer be used to collect data from the pipelines. * <p> * Here we stop the <code>Reactor</code> first, this ensures * that there are no further selects performed if a given socket * does not have enough data to fulfil a request. From there we * stop the main dispatch <code>Executor</code> so that all of * the currently executing tasks complete. The final stage of * termination requires the collector thread pool to be stopped. */ public void stop() throws IOException { try { reactor.stop(); executor.stop(); collect.stop(); } catch(Exception cause) { throw new TransportException("Error stopping", cause); } } }
/** * This is used to flush all queued packets to the underlying * socket. If all of the queued packets have been fully written * then this returns true, otherwise this will return false. * * @return true if all queued packets are flushed to the socket */ public synchronized boolean flush() throws IOException { BufferSegment segment = compacter.build(); while(segment != null) { int size = write(segment); if(size < 0) { throw new TransportException("Connection reset"); } if(size == 0) { break; } segment = compacter.build(); } return complete(); }