Refine search
/** * Add the given {@code msg} and {@link ChannelPromise}. */ public void add(Object msg, ChannelPromise promise) { assert ctx.executor().inEventLoop(); if (msg == null) { throw new NullPointerException("msg"); } if (promise == null) { throw new NullPointerException("promise"); } // It is possible for writes to be triggered from removeAndFailAll(). To preserve ordering, // we should add them to the queue and let removeAndFailAll() fail them later. int messageSize = size(msg); PendingWrite write = PendingWrite.newInstance(msg, messageSize, promise); PendingWrite currentTail = tail; if (currentTail == null) { tail = head = write; } else { currentTail.next = write; tail = write; } size ++; bytes += messageSize; tracker.incrementPendingOutboundBytes(write.size); }
private void addPendingWrite(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { PendingWriteQueue pendingWrites = this.pendingWrites; if (pendingWrites == null) { this.pendingWrites = pendingWrites = new PendingWriteQueue(ctx); } pendingWrites.add(msg, promise); }
assert ctx.executor().inEventLoop(); if (isEmpty()) { return null; ChannelPromise p = ctx.newPromise(); PromiseCombiner combiner = new PromiseCombiner(); try { Object msg = write.msg; ChannelPromise promise = write.promise; recycle(write, false); if (!(promise instanceof VoidChannelPromise)) { combiner.add(promise); ctx.write(msg, promise); write = next; p.setFailure(cause); assertEmpty(); return p;
/** * Remove a pending write operation and fail it with the given {@link Throwable}. The message will be released via * {@link ReferenceCountUtil#safeRelease(Object)}. */ public void removeAndFail(Throwable cause) { assert ctx.executor().inEventLoop(); if (cause == null) { throw new NullPointerException("cause"); } PendingWrite write = head; if (write == null) { return; } ReferenceCountUtil.safeRelease(write.msg); ChannelPromise promise = write.promise; safeFail(promise, cause); recycle(write, true); }
/** * Removes a pending write operation and performs it via * {@link ChannelHandlerContext#write(Object, ChannelPromise)}. * * @return {@link ChannelFuture} if something was written and {@code null} * if the {@link PendingWriteQueue} is empty. */ public ChannelFuture removeAndWrite() { assert ctx.executor().inEventLoop(); PendingWrite write = head; if (write == null) { return null; } Object msg = write.msg; ChannelPromise promise = write.promise; recycle(write, true); return ctx.write(msg, promise); }
@SuppressWarnings("unchecked") protected synchronized void trySendingMessages(ChannelHandlerContext ctx) { while (queue.size() > 0) { // Get the RequestItem that is up next in the queue. PlcRequestContainer currentItem = (PlcRequestContainer) queue.current(); InternalPlcRequest request = currentItem.getRequest(); // Send the TPDU. try { ChannelFuture channelFuture = queue.removeAndWrite(); ctx.flush(); if (channelFuture == null) { break; } } catch (Exception e) { LOGGER.error("Error sending more queues messages", e); ctx.fireExceptionCaught(e); } if (request instanceof CorrelatedPlcRequest) { CorrelatedPlcRequest correlatedPlcRequest = (CorrelatedPlcRequest) request; // Add it to the list of sentButUnacknowledgedSubContainer. sentButUnacknowledgedSubContainer.put(correlatedPlcRequest.getTdpu(), currentItem); LOGGER.debug("container with id {} sent: ", correlatedPlcRequest.getTdpu(), currentItem); } } ctx.flush(); }
@Override public void channelRegistered(ChannelHandlerContext ctx) { this.queue = new PendingWriteQueue(ctx); try { Field prevField = FieldUtils.getField(ctx.getClass(), "prev", true); if(prevField != null) { ChannelHandlerContext prevContext = (ChannelHandlerContext) prevField.get(ctx); prevChannelHandler = prevContext.handler(); } } catch(Exception e) { logger.error("Error accessing field 'prev'", e); } }
private void writePendingWrites() { if (pendingWrites != null) { pendingWrites.removeAndWriteAll(); pendingWrites = null; } }
public Map<String, Number> getStatistics() { HashMap<String, Number> statistics = new HashMap<>(); statistics.put("queue", queue.size()); statistics.put("sentButUnacknowledgedSubContainer", sentButUnacknowledgedSubContainer.size()); statistics.put("correlationToParentContainer", correlationToParentContainer.size()); statistics.put("containerCorrelationIdMap", containerCorrelationIdMap.size()); statistics.put("responsesToBeDelivered", responsesToBeDelivered.size()); statistics.put("correlationIdGenerator", correlationIdGenerator.get()); statistics.put("deliveredItems", deliveredItems.get()); statistics.put("erroredItems", erroredItems.get()); statistics.put("deliveredContainers", deliveredContainers.get()); statistics.put("erroredContainers", erroredContainers.get()); return statistics; }
private void writeS7Message(Channel channel, PromiseCombiner promiseCombiner, S7Message message, ByteBuf buf) throws PlcProtocolException { encodeHeader(message, buf); encodeParameters(message, buf); encodePayloads(message, buf); // Check if the message doesn't exceed the negotiated maximum size. if (buf.writerIndex() > pduSize) { throw new PlcProtocolPayloadTooBigException("s7", pduSize, buf.writerIndex(), message); } else { ChannelPromise subPromise = new DefaultChannelPromise(channel); queue.add(new DataTpdu(true, (byte) 0x01, Collections.emptyList(), buf, message), subPromise); promiseCombiner.add((Future) subPromise); logger.debug("S7 Message with id {} queued", message.getTpduReference()); } }
@Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { this.queue = new PendingWriteQueue(ctx); this.scheduledTimeouts = new ConcurrentHashMap<>(); this.sentButUnacknowledgedSubContainer = new ConcurrentHashMap<>(); this.correlationToParentContainer = new ConcurrentHashMap<>(); this.containerCorrelationIdMap = new ConcurrentHashMap<>(); this.responsesToBeDelivered = new ConcurrentHashMap<>(); this.correlationIdGenerator = new AtomicInteger(); this.deliveredItems = new AtomicLong(); this.erroredItems = new AtomicLong(); this.deliveredContainers = new AtomicLong(); this.erroredContainers = new AtomicLong(); super.channelRegistered(ctx); }
private void failPendingWrites(Throwable cause) { if (pendingWrites != null) { pendingWrites.removeAndFailAll(cause); pendingWrites = null; } }
/** * Removes a pending write operation and performs it via * {@link ChannelHandlerContext#write(Object, ChannelPromise)}. * * @return {@link ChannelFuture} if something was written and {@code null} * if the {@link PendingWriteQueue} is empty. */ public ChannelFuture removeAndWrite() { assert ctx.executor().inEventLoop(); PendingWrite write = head; if (write == null) { return null; } Object msg = write.msg; ChannelPromise promise = write.promise; recycle(write, true); return ctx.write(msg, promise); }
/** * Removes a pending write operation and release it's message via {@link ReferenceCountUtil#safeRelease(Object)}. * * @return {@link ChannelPromise} of the pending write or {@code null} if the queue is empty. * */ public ChannelPromise remove() { assert ctx.executor().inEventLoop(); PendingWrite write = head; if (write == null) { return null; } ChannelPromise promise = write.promise; ReferenceCountUtil.safeRelease(write.msg); recycle(write, true); return promise; }
private void writePendingWrites() { if (pendingWrites != null) { pendingWrites.removeAndWriteAll(); pendingWrites = null; } }
PlcRequestContainer<CorrelatedPlcReadRequest, InternalPlcResponse> correlatedPlcRequestContainer = new PlcRequestContainer<>(CorrelatedPlcReadRequest.of(reader, field, tdpu), correlatedCompletableFuture); correlationToParentContainer.put(tdpu, in); queue.add(correlatedPlcRequestContainer, subPromise); if (!tdpus.add(tdpu)) { throw new IllegalStateException("AtomicInteger should not create duplicated ids: " + tdpu); PlcRequestContainer<CorrelatedPlcWriteRequest, InternalPlcResponse> correlatedPlcRequestContainer = new PlcRequestContainer<>(CorrelatedPlcWriteRequest.of(writer, fieldItemTriple, tdpu), correlatedCompletableFuture); correlationToParentContainer.put(tdpu, in); queue.add(correlatedPlcRequestContainer, subPromise); if (!tdpus.add(tdpu)) { throw new IllegalStateException("AtomicInteger should not create duplicated ids: " + tdpu); PlcRequestContainer<CorrelatedPlcSubscriptionRequest, InternalPlcResponse> correlatedPlcRequestContainer = new PlcRequestContainer<>(CorrelatedPlcSubscriptionRequest.of(subscriber, field, tdpu), correlatedCompletableFuture); correlationToParentContainer.put(tdpu, in); queue.add(correlatedPlcRequestContainer, subPromise); if (!tdpus.add(tdpu)) { throw new IllegalStateException("AtomicInteger should not create duplicated ids: " + tdpu); PlcRequestContainer<CorrelatedPlcUnsubscriptionRequest, InternalPlcResponse> correlatedPlcRequestContainer = new PlcRequestContainer<>(CorrelatedPlcUnsubscriptionRequest.of(subscriber, handle, tdpu), correlatedCompletableFuture); correlationToParentContainer.put(tdpu, in); queue.add(correlatedPlcRequestContainer, subPromise); if (!tdpus.add(tdpu)) { throw new IllegalStateException("AtomicInteger should not create duplicated ids: " + tdpu); } else { ChannelPromise subPromise = new DefaultChannelPromise(promise.channel()); queue.add(msg, subPromise); promiseCombiner.add((Future) subPromise);
private void failPendingWrites(Throwable cause) { if (pendingWrites != null) { pendingWrites.removeAndFailAll(cause); pendingWrites = null; } }
assert ctx.executor().inEventLoop(); if (isEmpty()) { return null; ChannelPromise p = ctx.newPromise(); PromiseCombiner combiner = new PromiseCombiner(); try { Object msg = write.msg; ChannelPromise promise = write.promise; recycle(write, false); if (!(promise instanceof VoidChannelPromise)) { combiner.add(promise); ctx.write(msg, promise); write = next; p.setFailure(cause); assertEmpty(); return p;
/** * Removes a pending write operation and performs it via * {@link ChannelHandlerContext#write(Object, ChannelPromise)}. * * @return {@link ChannelFuture} if something was written and {@code null} * if the {@link PendingWriteQueue} is empty. */ public ChannelFuture removeAndWrite() { assert ctx.executor().inEventLoop(); PendingWrite write = head; if (write == null) { return null; } Object msg = write.msg; ChannelPromise promise = write.promise; recycle(write, true); return ctx.write(msg, promise); }
/** * Remove all pending write operation and fail them with the given {@link Throwable}. The message will be released * via {@link ReferenceCountUtil#safeRelease(Object)}. */ public void removeAndFailAll(Throwable cause) { assert ctx.executor().inEventLoop(); if (cause == null) { throw new NullPointerException("cause"); } // It is possible for some of the failed promises to trigger more writes. The new writes // will "revive" the queue, so we need to clean them up until the queue is empty. for (PendingWrite write = head; write != null; write = head) { head = tail = null; size = 0; bytes = 0; while (write != null) { PendingWrite next = write.next; ReferenceCountUtil.safeRelease(write.msg); ChannelPromise promise = write.promise; recycle(write, false); safeFail(promise, cause); write = next; } } assertEmpty(); }