/** * Append data to the store. * Because ordering dictates that there only be one outstanding append from a given connection, this is implemented * by adding the append to a queue. */ @Override public void append(Append append) { log.trace("Processing append received from client {}", append); UUID id = append.getWriterId(); synchronized (lock) { Long lastEventNumber = latestEventNumbers.get(Pair.of(append.getSegment(), id)); Preconditions.checkState(lastEventNumber != null, "Data from unexpected connection: %s.", id); Preconditions.checkState(append.getEventNumber() >= lastEventNumber, "Event was already appended."); waitingAppends.put(id, append); } pauseOrResumeReading(); performNextWrite(); }
private CompletableFuture<Void> storeAppend(Append append) { long lastEventNumber; synchronized (lock) { lastEventNumber = latestEventNumbers.get(Pair.of(append.getSegment(), append.getWriterId())); } List<AttributeUpdate> attributes = Arrays.asList( new AttributeUpdate(append.getWriterId(), AttributeUpdateType.ReplaceIfEquals, append.getEventNumber(), lastEventNumber), new AttributeUpdate(EVENT_COUNT, AttributeUpdateType.Accumulate, append.getEventCount())); ByteBuf buf = append.getData().asReadOnly(); byte[] bytes = new byte[buf.readableBytes()]; buf.readBytes(bytes); if (append.isConditional()) { return store.append(append.getSegment(), append.getExpectedLength(), bytes, attributes, TIMEOUT); } else { return store.append(append.getSegment(), bytes, attributes, TIMEOUT); } }
String segment = last.getSegment(); long eventNumber = last.getEventNumber(); outstandingAppend = new Append(segment, writer, eventNumber, eventCount, data, null);
long previousEventNumber; synchronized (lock) { previousEventNumber = latestEventNumbers.get(Pair.of(append.getSegment(), append.getWriterId())); Preconditions.checkState(outstandingAppend == append, "Synchronization error in: %s while processing append: %s.", connection.send(new ConditionalCheckFailed(append.getWriterId(), append.getEventNumber())); } else { handleException(append.getWriterId(), append.getEventNumber(), append.getSegment(), "appending data", exception); if (statsRecorder != null && !StreamSegmentNameUtils.isTransactionSegment(append.getSegment())) { statsRecorder.record(append.getSegment(), append.getDataLength(), append.getEventCount()); if (!StreamSegmentNameUtils.isTransactionSegment(append.getSegment())) { dynamicLogger.incCounterValue(nameFromSegment(SEGMENT_WRITE_BYTES, append.getSegment()), append.getDataLength()); dynamicLogger.incCounterValue(nameFromSegment(SEGMENT_WRITE_EVENTS, append.getSegment()), append.getEventCount()); outstandingAppend = null; if (exception == null) { latestEventNumbers.put(Pair.of(append.getSegment(), append.getWriterId()), append.getEventNumber()); } else { if (!conditionalFailed) { waitingAppends.removeAll(append.getWriterId()); latestEventNumbers.remove(Pair.of(append.getSegment(), append.getWriterId())); performNextWrite(); } catch (Throwable e) { handleException(append.getWriterId(), append.getEventNumber(), append.getSegment(), "handling append result", e);