@InternalApi void processOutstandingAckOperations() { List<PendingModifyAckDeadline> modifyAckDeadlinesToSend = new ArrayList<>(); List<String> acksToSend = new ArrayList<>(); pendingAcks.drainTo(acksToSend); logger.log(Level.FINER, "Sending {0} acks", acksToSend.size()); PendingModifyAckDeadline nacksToSend = new PendingModifyAckDeadline(0); pendingNacks.drainTo(nacksToSend.ackIds); logger.log(Level.FINER, "Sending {0} nacks", nacksToSend.ackIds.size()); if (!nacksToSend.ackIds.isEmpty()) { modifyAckDeadlinesToSend.add(nacksToSend); } PendingModifyAckDeadline receiptsToSend = new PendingModifyAckDeadline(getMessageDeadlineSeconds()); pendingReceipts.drainTo(receiptsToSend.ackIds); logger.log(Level.FINER, "Sending {0} receipts", receiptsToSend.ackIds.size()); if (!receiptsToSend.ackIds.isEmpty()) { modifyAckDeadlinesToSend.add(receiptsToSend); } ackProcessor.sendAckOperations(acksToSend, modifyAckDeadlinesToSend); }
@InternalApi void extendDeadlines() { int extendSeconds = getMessageDeadlineSeconds(); List<PendingModifyAckDeadline> modacks = new ArrayList<>(); PendingModifyAckDeadline modack = new PendingModifyAckDeadline(extendSeconds); Instant now = now(); Instant extendTo = now.plusSeconds(extendSeconds); for (Map.Entry<String, AckHandler> entry : pendingMessages.entrySet()) { String ackId = entry.getKey(); Instant totalExpiration = entry.getValue().totalExpiration; if (totalExpiration.isAfter(extendTo)) { modack.ackIds.add(ackId); continue; } // forget removes from pendingMessages; this is OK, concurrent maps can // handle concurrent iterations and modifications. entry.getValue().forget(); if (totalExpiration.isAfter(now)) { int sec = Math.max(1, (int) now.until(totalExpiration, ChronoUnit.SECONDS)); modacks.add(new PendingModifyAckDeadline(sec, ackId)); } } logger.log(Level.FINER, "Sending {0} modacks", modack.ackIds.size() + modacks.size()); modacks.add(modack); List<String> acksToSend = Collections.emptyList(); ackProcessor.sendAckOperations(acksToSend, modacks); }