Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented lobby concept with RScoredSortedSet #1454

Open
wants to merge 1 commit into
base: feature/throttling-service
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.concurrent.ConcurrentMap;
import org.opensmartgridplatform.throttling.entities.ThrottlingConfig;
import org.opensmartgridplatform.throttling.model.NetworkSegment;
import org.opensmartgridplatform.throttling.model.PermitRequest;
import org.opensmartgridplatform.throttling.model.ThrottlingSettings;
import org.opensmartgridplatform.throttling.repositories.ThrottlingConfigRepository;
import org.opensmartgridplatform.throttling.services.PermitService;
Expand Down Expand Up @@ -99,7 +100,7 @@ public boolean requestPermit(
networkSegment.throttlingConfigId(), this::createAndInitialize);

return permitsPerNetworkSegment.requestPermit(
networkSegment, clientId, requestId, priority, throttlingSettings);
networkSegment, new PermitRequest(clientId, requestId), priority, throttlingSettings);
}

private PermitsPerNetworkSegment createAndInitialize(final short throttlingConfigId) {
Expand Down Expand Up @@ -133,15 +134,19 @@ public boolean releasePermit(
final PermitsPerNetworkSegment permitsPerNetworkSegment =
this.permitsPerSegmentByConfig.get(networkSegment.throttlingConfigId());
return permitsPerNetworkSegment != null
&& permitsPerNetworkSegment.releasePermit(networkSegment, clientId, requestId);
&& permitsPerNetworkSegment.releasePermit(
networkSegment, new PermitRequest(clientId, requestId));
}

public boolean discardPermit(final int clientId, final int requestId) {
return this.permitService
.findByClientIdAndRequestId(clientId, requestId)
.map(
permit ->
this.releasePermit(permit.networkSegment(), permit.clientId(), permit.requestId()))
this.releasePermit(
permit.networkSegment(),
permit.permitRequest().getClientId(),
permit.permitRequest().getRequestId()))
.orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.extern.slf4j.Slf4j;
import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum;
import org.opensmartgridplatform.throttling.model.NetworkSegment;
import org.opensmartgridplatform.throttling.model.PermitRequest;
import org.opensmartgridplatform.throttling.model.ThrottlingSettings;
import org.opensmartgridplatform.throttling.services.PermitService;
import org.opensmartgridplatform.throttling.services.RateLimitService;
Expand Down Expand Up @@ -36,8 +37,7 @@ public PermitsPerNetworkSegment(

public boolean requestPermit(
final NetworkSegment networkSegment,
final int clientId,
final int requestId,
final PermitRequest permitRequest,
final int priority,
final ThrottlingSettings throttlingSettings) {

Expand All @@ -46,24 +46,24 @@ public boolean requestPermit(
networkSegment.baseTransceiverStationId(), networkSegment.cellId(), throttlingSettings);

if (newConnectionRequestAllowed) {
log.debug("Request [{}] for permit is allowed by rate-limiter", requestId);
log.debug("Request [{}] for permit is allowed by rate-limiter", permitRequest.getRequestId());
return this.tryAcquiringPermit(
networkSegment, clientId, requestId, priority, throttlingSettings.getMaxConcurrency());
networkSegment, permitRequest, priority, throttlingSettings.getMaxConcurrency());
}

log.debug("Request [{}] for permit is NOT allowed by rate-limiter", requestId);
log.debug(
"Request [{}] for permit is NOT allowed by rate-limiter", permitRequest.getRequestId());
return false;
}

public boolean releasePermit(
final NetworkSegment networkSegment, final int clientId, final int requestId) {
return this.permitService.removePermit(networkSegment, clientId, requestId);
final NetworkSegment networkSegment, final PermitRequest permitRequest) {
return this.permitService.removePermit(networkSegment, permitRequest);
}

private boolean tryAcquiringPermit(
final NetworkSegment networkSegment,
final int clientId,
final int requestId,
final PermitRequest permitRequest,
final int priority,
final int maxConcurrency) {

Expand All @@ -72,23 +72,26 @@ private boolean tryAcquiringPermit(
return false;
}

final boolean highPrio =
this.highPrioPoolEnabled && priority > MessagePriorityEnum.DEFAULT.getPriority();

final boolean granted =
this.permitService.createPermit(networkSegment, clientId, requestId, maxConcurrency);
this.permitService.createPermit(networkSegment, permitRequest, maxConcurrency, highPrio);

if (granted) {
log.debug("Request [{}] is granted a permit.", requestId);
log.debug("Request [{}] is granted a permit.", permitRequest.getRequestId());
return true;

} else {
log.debug("Request [{}], is NOT granted a permit.", requestId);
log.debug("Request [{}], is NOT granted a permit.", permitRequest.getRequestId());

if (this.highPrioPoolEnabled && priority > MessagePriorityEnum.DEFAULT.getPriority()) {
if (highPrio) {
log.debug(
"Request [{}] is a high priority request and high priority pool is enabled -> we will wait for a permit release...",
requestId);
permitRequest.getRequestId());

return this.waitUntilPermitIsAvailable(
networkSegment, clientId, requestId, maxConcurrency, this.maxWaitForHighPrioInMs);
networkSegment, permitRequest, maxConcurrency, this.maxWaitForHighPrioInMs);
}
}

Expand All @@ -97,19 +100,20 @@ private boolean tryAcquiringPermit(

private boolean waitUntilPermitIsAvailable(
final NetworkSegment networkSegment,
final int clientId,
final int requestId,
final PermitRequest permitRequest,
final int maxConcurrency,
final int maxWaitForHighPrioInMs) {

final long startTime = System.currentTimeMillis();

log.debug("High priority request [{}] is waiting until permit is available.", requestId);
log.debug(
"High priority request [{}] is waiting until permit is available.",
permitRequest.getRequestId());

while (System.currentTimeMillis() - startTime < maxWaitForHighPrioInMs) {

final boolean granted =
this.permitService.createPermit(networkSegment, clientId, requestId, maxConcurrency);
this.permitService.createPermit(networkSegment, permitRequest, maxConcurrency, true);

if (!granted) {

Expand All @@ -124,7 +128,7 @@ private boolean waitUntilPermitIsAvailable(
continue;
}

log.debug("High priority request [{}] is granted a permit.", requestId);
log.debug("High priority request [{}] is granted a permit.", permitRequest.getRequestId());
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

package org.opensmartgridplatform.throttling.model;

public record Permit(NetworkSegment networkSegment, int clientId, int requestId) {}
public record Permit(NetworkSegment networkSegment, PermitRequest permitRequest) {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class PermitKey {

private static final String KEY_FORMAT = "osgp-network-segment-permit-%s_%s_%s";
private static final String LOCK_FORMAT = "osgp-network-segment-lock-%s_%s_%s";
private static final String LOBBY_FORMAT = "osgp-network-segment-lobby-%s_%s_%s";

private short throttlingConfigID;
private int baseTransceiverStationId;
Expand Down Expand Up @@ -42,6 +43,14 @@ public String lockId() {
this.asString(this.cellId));
}

public String lobby() {
return String.format(
LOBBY_FORMAT,
this.asString(this.throttlingConfigID),
this.asString(this.baseTransceiverStationId),
this.asString(this.cellId));
}

private String asString(final int value) {
return this.asString(value, false);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.opensmartgridplatform.throttling.model;

import java.util.UUID;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@EqualsAndHashCode
@Getter
public class PermitRequest {
final int clientId;
final int requestId;
final UUID uuid;

public PermitRequest(final int clientId, final int requestId) {
this.clientId = clientId;
this.requestId = requestId;
this.uuid = UUID.randomUUID();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
import java.util.Optional;
import org.opensmartgridplatform.throttling.model.NetworkSegment;
import org.opensmartgridplatform.throttling.model.Permit;
import org.opensmartgridplatform.throttling.model.PermitRequest;

public interface PermitService {

boolean createPermit(
final NetworkSegment networkSegment,
final int clientId,
final int requestId,
final int maxConcurrentRequests);
NetworkSegment networkSegment,
PermitRequest permitRequest,
int maxConcurrentRequests,
boolean highPrioRequest);

boolean removePermit(
final NetworkSegment networkSegment, final int clientId, final int requestId);
boolean removePermit(NetworkSegment networkSegment, PermitRequest permitRequest);

Optional<Permit> findByClientIdAndRequestId(int clientId, int requestId);

Expand Down
Loading
Loading