io.zeebe.logstreams.impl.backpressure.AppendEntryLimiter Maven / Gradle / Ivy
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
* one or more contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright ownership.
* Licensed under the Zeebe Community License 1.0. You may not use this file
* except in compliance with the Zeebe Community License 1.0.
*/
package io.zeebe.logstreams.impl.backpressure;
import com.netflix.concurrency.limits.limiter.AbstractLimiter;
import io.zeebe.logstreams.impl.Loggers;
import java.util.Optional;
import org.agrona.collections.Long2ObjectHashMap;
public final class AppendEntryLimiter extends AbstractLimiter implements AppendLimiter {
private final Long2ObjectHashMap appendedListeners = new Long2ObjectHashMap<>();
private final AppendBackpressureMetrics metrics;
private AppendEntryLimiter(final AppendEntryLimiterBuilder builder, final int partitionId) {
super(builder);
metrics = new AppendBackpressureMetrics(partitionId);
metrics.setInflight(0);
metrics.setNewLimit(getLimit());
}
public Optional acquire(final Long position) {
if (getInflight() >= getLimit()) {
return createRejectedListener();
}
final Listener listener = createListener();
return Optional.of(listener);
}
private void registerListener(final long position, final Listener listener) {
appendedListeners.put(position, listener);
}
public boolean tryAcquire(final Long position) {
final Optional acquired = acquire(position);
return acquired
.map(
listener -> {
registerListener(position, listener);
metrics.incInflight();
return true;
})
.orElse(false);
}
public void onCommit(final long position) {
final Listener listener = appendedListeners.remove(position);
if (listener != null) {
listener.onSuccess();
metrics.decInflight();
} else {
Loggers.LOGSTREAMS_LOGGER.warn(
"We encountered an problem on releasing the acquired in flight append."
+ " There was no listener registered for the given position {}, this should not happen.",
position);
}
}
@Override
protected void onNewLimit(final int newLimit) {
super.onNewLimit(newLimit);
metrics.setNewLimit(newLimit);
}
public static AppendEntryLimiterBuilder builder() {
return new AppendEntryLimiterBuilder();
}
public static class AppendEntryLimiterBuilder
extends AbstractLimiter.Builder {
private int partitionId;
@Override
protected AppendEntryLimiterBuilder self() {
return this;
}
public AppendEntryLimiterBuilder partitionId(final int partition) {
partitionId = partition;
return this;
}
public AppendEntryLimiter build() {
return new AppendEntryLimiter(this, partitionId);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy