use of org.webpieces.nio.api.channels.Channel in project webpieces by deanhiller.
the class ConnectedChannels method closeChannels.
public CompletableFuture<Void> closeChannels() {
//first prevent other threads from calling above functions ever again
closed = true;
List<CompletableFuture<Channel>> futures = new ArrayList<>();
for (Channel c : connectedChannels.keySet()) {
futures.add(c.close());
}
@SuppressWarnings("rawtypes") CompletableFuture[] array = futures.toArray(new CompletableFuture[0]);
return CompletableFuture.allOf(array);
}
use of org.webpieces.nio.api.channels.Channel in project webpieces by deanhiller.
the class TestBasicSsl method testBasic.
@Test
public void testBasic() throws InterruptedException, ExecutionException {
ChannelManager svrMgr = createSvrChanMgr("server");
SelfSignedSSLEngineFactory sslFactory = new SelfSignedSSLEngineFactory();
TCPServerChannel svrChannel = svrMgr.createTCPServerChannel("svrChan", mockConnListener, sslFactory);
svrChannel.bind(new InetSocketAddress(8444));
int port = svrChannel.getLocalAddress().getPort();
//don't really need to use a separate chan mgr but we will here..
ChannelManager chanMgr = createSvrChanMgr("client");
TCPChannel channel = chanMgr.createTCPChannel("client", sslFactory.createEngineForClient("cvs.xsoftware.biz", port));
CompletableFuture<Channel> future = channel.connect(new InetSocketAddress("localhost", port), mockClientDataListener);
future.get();
byte[] data = new byte[] { 0, 2, 4, 6, 8, 10 };
ByteBuffer buf = ByteBuffer.wrap(data);
channel.write(buf);
ByteBuffer result = mockSvrDataListener.getFirstBuffer().get();
byte[] newData = new byte[result.remaining()];
result.get(newData);
Assert.assertEquals(data.length, newData.length);
for (int i = 0; i < data.length; i++) {
Assert.assertEquals(data[i], newData[i]);
}
//verify sniServerName was used in looking up security cert.
String host = sslFactory.getCachedHost();
Assert.assertEquals("cvs.xsoftware.biz", host);
}
use of org.webpieces.nio.api.channels.Channel in project webpieces by deanhiller.
the class BasChannelImpl method unqueueAndFailWritesThenClose.
private void unqueueAndFailWritesThenClose(CloseRunnable action) {
List<CompletableFuture<Channel>> promises;
synchronized (this) {
//put here for emphasis that we are synchronizing here but not below
promises = failAllWritesInQueue();
}
//TODO: This should really be inlined now. It's a remnant of an old design since close didn't
//work well outside the selector thread previously
action.runDelayedAction();
//notify clients outside the synchronization block!!!
for (CompletableFuture<Channel> promise : promises) {
log.info("WRITES outstanding while close was called, notifying client through his failure method of the exception");
//we only incur the cost of Throwable.fillInStackTrace() if we will use this exception
//(it's called in the Throwable constructor) so we don't do this on every close channel
NioClosedChannelException closeExc = new NioClosedChannelException("There are " + promises.size() + " writes that are not complete yet(you called write but " + "they did not call success back to the client).");
promise.completeExceptionally(closeExc);
}
}
use of org.webpieces.nio.api.channels.Channel in project webpieces by deanhiller.
the class BasChannelImpl method writeAll.
/**
* This method is reading from the queue and writing out to the socket buffers that
* did not get written out when client called write.
*
*/
void writeAll() {
List<CompletableFuture<Channel>> finishedPromises = new ArrayList<>();
synchronized (writeLock) {
if (dataToBeWritten.isEmpty())
throw new IllegalStateException("bug, I am not sure this is possible..it shouldn't be...look into");
while (!dataToBeWritten.isEmpty()) {
WriteInfo writer = dataToBeWritten.peek();
ByteBuffer buffer = writer.getBuffer();
int initialSize = buffer.remaining();
int wroteOut = this.writeImpl(buffer);
if (buffer.hasRemaining()) {
if (buffer.remaining() + wroteOut != initialSize)
throw new IllegalStateException("Something went wrong. b.remaining()=" + buffer.remaining() + " written=" + wroteOut + " total=" + initialSize);
log.trace(() -> this + "Did not write all data out");
int leftOverSize = buffer.remaining();
int writtenOut = initialSize - leftOverSize;
waitingBytesCounter -= writtenOut;
break;
}
//if it finished, remove the item from the queue. It
//does not need to be run again.
dataToBeWritten.poll();
//release bytebuffer back to pool
pool.releaseBuffer(writer.getBuffer());
waitingBytesCounter -= initialSize;
finishedPromises.add(writer.getPromise());
}
//we are only applying backpressure when queue is too large
boolean applyPressure = !dataToBeWritten.isEmpty();
boolean changedValue = applyingBackpressure.compareAndSet(true, applyPressure);
if (!applyPressure && changedValue) {
//we only fire when the value of applyingBackpressure changes
dataListener.releaseBackPressure(this);
}
//we are registered for writes with ANY size queue
if (dataToBeWritten.isEmpty() && inDelayedWriteMode) {
inDelayedWriteMode = false;
log.trace(() -> this + "unregister writes");
Helper.unregisterSelectableChannel(this, SelectionKey.OP_WRITE);
}
}
//MAKE SURE to notify clients outside of synchronization block so no deadlocks with their locks
for (CompletableFuture<Channel> promise : finishedPromises) {
promise.complete(this);
}
}
use of org.webpieces.nio.api.channels.Channel in project webpieces by deanhiller.
the class DelayServerAcceptor method closeAllSockets.
public void closeAllSockets() throws IOException {
for (int i = 0; i < sockets.size(); i++) {
Channel channel = sockets.get(i);
channel.oldClose();
}
}
Aggregations