Skip to content

Commit 41f831e

Browse files
authored
Merge pull request #1451 from OSGP/feature/throttling-service
Feature/throttling service
2 parents 520db8e + fe16ddc commit 41f831e

File tree

15 files changed

+303
-263
lines changed

15 files changed

+303
-263
lines changed

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfig.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.concurrent.ConcurrentMap;
1313
import org.opensmartgridplatform.throttling.entities.ThrottlingConfig;
1414
import org.opensmartgridplatform.throttling.model.NetworkSegment;
15+
import org.opensmartgridplatform.throttling.model.PermitRequest;
1516
import org.opensmartgridplatform.throttling.model.ThrottlingSettings;
1617
import org.opensmartgridplatform.throttling.repositories.ThrottlingConfigRepository;
1718
import org.opensmartgridplatform.throttling.services.PermitService;
@@ -34,19 +35,21 @@ public class PermitsByThrottlingConfig {
3435
private final RateLimitService rateLimitService;
3536
private final boolean highPrioPoolEnabled;
3637
private final int maxWaitForHighPrioInMs;
38+
private final int pauseWaitForHighPrioInMs;
3739

3840
public PermitsByThrottlingConfig(
3941
final ThrottlingConfigRepository throttlingConfigRepository,
4042
final PermitService permitService,
4143
final RateLimitService rateLimitService,
4244
@Value("${wait.for.high.prio.enabled:true}") final boolean highPrioPoolEnabled,
43-
@Value("${wait.for.high.prio.max.in.ms:10000}") final int maxWaitForHighPrioInMs) {
44-
45+
@Value("${wait.for.high.prio.max.in.ms:10000}") final int maxWaitForHighPrioInMs,
46+
@Value("${wait.for.high.prio.pause.in.ms:200}") final int pauseWaitForHighPrioInMs) {
4547
this.throttlingConfigRepository = throttlingConfigRepository;
4648
this.permitService = permitService;
4749
this.rateLimitService = rateLimitService;
4850
this.highPrioPoolEnabled = highPrioPoolEnabled;
4951
this.maxWaitForHighPrioInMs = maxWaitForHighPrioInMs;
52+
this.pauseWaitForHighPrioInMs = pauseWaitForHighPrioInMs;
5053
}
5154

5255
/** Clears all cached permit counts and initializes the cached information from the database. */
@@ -67,7 +70,8 @@ public void initialize() {
6770
this.permitService,
6871
this.rateLimitService,
6972
this.highPrioPoolEnabled,
70-
this.maxWaitForHighPrioInMs)));
73+
this.maxWaitForHighPrioInMs,
74+
this.pauseWaitForHighPrioInMs)));
7175

7276
/* Remove config not in database */
7377
final List<Short> throttlingConfigIdsToBeRemoved =
@@ -96,15 +100,16 @@ public boolean requestPermit(
96100
networkSegment.throttlingConfigId(), this::createAndInitialize);
97101

98102
return permitsPerNetworkSegment.requestPermit(
99-
networkSegment, clientId, requestId, priority, throttlingSettings);
103+
networkSegment, new PermitRequest(clientId, requestId), priority, throttlingSettings);
100104
}
101105

102106
private PermitsPerNetworkSegment createAndInitialize(final short throttlingConfigId) {
103107
return new PermitsPerNetworkSegment(
104108
this.permitService,
105109
this.rateLimitService,
106110
this.highPrioPoolEnabled,
107-
this.maxWaitForHighPrioInMs);
111+
this.maxWaitForHighPrioInMs,
112+
this.pauseWaitForHighPrioInMs);
108113
}
109114

110115
public void newThrottlingConfigCreated(final short throttlingConfigId) {
@@ -119,7 +124,8 @@ public void newThrottlingConfigCreated(final short throttlingConfigId) {
119124
this.permitService,
120125
this.rateLimitService,
121126
this.highPrioPoolEnabled,
122-
this.maxWaitForHighPrioInMs));
127+
this.maxWaitForHighPrioInMs,
128+
this.pauseWaitForHighPrioInMs));
123129
}
124130

125131
public boolean releasePermit(
@@ -128,15 +134,19 @@ public boolean releasePermit(
128134
final PermitsPerNetworkSegment permitsPerNetworkSegment =
129135
this.permitsPerSegmentByConfig.get(networkSegment.throttlingConfigId());
130136
return permitsPerNetworkSegment != null
131-
&& permitsPerNetworkSegment.releasePermit(networkSegment, clientId, requestId);
137+
&& permitsPerNetworkSegment.releasePermit(
138+
networkSegment, new PermitRequest(clientId, requestId));
132139
}
133140

134141
public boolean discardPermit(final int clientId, final int requestId) {
135142
return this.permitService
136143
.findByClientIdAndRequestId(clientId, requestId)
137144
.map(
138145
permit ->
139-
this.releasePermit(permit.networkSegment(), permit.clientId(), permit.requestId()))
146+
this.releasePermit(
147+
permit.networkSegment(),
148+
permit.permitRequest().getClientId(),
149+
permit.permitRequest().getRequestId()))
140150
.orElse(false);
141151
}
142152
}

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,66 @@
44

55
package org.opensmartgridplatform.throttling;
66

7+
import java.util.concurrent.TimeUnit;
78
import lombok.extern.slf4j.Slf4j;
89
import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum;
910
import org.opensmartgridplatform.throttling.model.NetworkSegment;
11+
import org.opensmartgridplatform.throttling.model.PermitRequest;
1012
import org.opensmartgridplatform.throttling.model.ThrottlingSettings;
1113
import org.opensmartgridplatform.throttling.services.PermitService;
1214
import org.opensmartgridplatform.throttling.services.RateLimitService;
1315

1416
@Slf4j
1517
public class PermitsPerNetworkSegment {
18+
1619
private final PermitService permitService;
1720
private final RateLimitService rateLimitService;
1821
private final boolean highPrioPoolEnabled;
1922
private final int maxWaitForHighPrioInMs;
23+
private final int pauseWaitForHighPrioInMs;
2024

2125
public PermitsPerNetworkSegment(
2226
final PermitService permitService,
2327
final RateLimitService rateLimitService,
2428
final boolean highPrioPoolEnabled,
25-
final int maxWaitForHighPrioInMs) {
29+
final int maxWaitForHighPrioInMs,
30+
final int pauseWaitForHighPrioInMs) {
2631
this.permitService = permitService;
2732
this.rateLimitService = rateLimitService;
2833
this.highPrioPoolEnabled = highPrioPoolEnabled;
2934
this.maxWaitForHighPrioInMs = maxWaitForHighPrioInMs;
35+
this.pauseWaitForHighPrioInMs = pauseWaitForHighPrioInMs;
3036
}
3137

3238
public boolean requestPermit(
3339
final NetworkSegment networkSegment,
34-
final int clientId,
35-
final int requestId,
40+
final PermitRequest permitRequest,
3641
final int priority,
3742
final ThrottlingSettings throttlingSettings) {
3843

3944
final boolean newConnectionRequestAllowed =
4045
this.rateLimitService.isNewConnectionRequestAllowed(
4146
networkSegment.baseTransceiverStationId(), networkSegment.cellId(), throttlingSettings);
4247

43-
log.debug(
44-
"Request [{}] for permit is {} by rate-limiter",
45-
requestId,
46-
newConnectionRequestAllowed ? "allowed" : "NOT allowed");
47-
4848
if (newConnectionRequestAllowed) {
49-
log.debug("Request [{}] for permit is allowed by rate-limiter", requestId);
49+
log.debug("Request [{}] for permit is allowed by rate-limiter", permitRequest.getRequestId());
5050
return this.tryAcquiringPermit(
51-
networkSegment, clientId, requestId, priority, throttlingSettings.getMaxConcurrency());
51+
networkSegment, permitRequest, priority, throttlingSettings.getMaxConcurrency());
5252
}
5353

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

5859
public boolean releasePermit(
59-
final NetworkSegment networkSegment, final int clientId, final int requestId) {
60-
return this.permitService.removePermit(networkSegment, clientId, requestId);
60+
final NetworkSegment networkSegment, final PermitRequest permitRequest) {
61+
return this.permitService.removePermit(networkSegment, permitRequest);
6162
}
6263

6364
private boolean tryAcquiringPermit(
6465
final NetworkSegment networkSegment,
65-
final int clientId,
66-
final int requestId,
66+
final PermitRequest permitRequest,
6767
final int priority,
6868
final int maxConcurrency) {
6969

@@ -72,23 +72,26 @@ private boolean tryAcquiringPermit(
7272
return false;
7373
}
7474

75+
final boolean highPrio =
76+
this.highPrioPoolEnabled && priority > MessagePriorityEnum.DEFAULT.getPriority();
77+
7578
final boolean granted =
76-
this.permitService.createPermit(networkSegment, clientId, requestId, maxConcurrency);
79+
this.permitService.createPermit(networkSegment, permitRequest, maxConcurrency, highPrio);
7780

7881
if (granted) {
79-
log.debug("Request [{}] is granted a permit.", requestId);
82+
log.debug("Request [{}] is granted a permit.", permitRequest.getRequestId());
8083
return true;
8184

8285
} else {
83-
log.debug("Request [{}], is NOT granted a permit.", requestId);
86+
log.debug("Request [{}], is NOT granted a permit.", permitRequest.getRequestId());
8487

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

9093
return this.waitUntilPermitIsAvailable(
91-
networkSegment, clientId, requestId, maxConcurrency, this.maxWaitForHighPrioInMs);
94+
networkSegment, permitRequest, maxConcurrency, this.maxWaitForHighPrioInMs);
9295
}
9396
}
9497

@@ -97,26 +100,35 @@ private boolean tryAcquiringPermit(
97100

98101
private boolean waitUntilPermitIsAvailable(
99102
final NetworkSegment networkSegment,
100-
final int clientId,
101-
final int requestId,
103+
final PermitRequest permitRequest,
102104
final int maxConcurrency,
103105
final int maxWaitForHighPrioInMs) {
104106

105107
final long startTime = System.currentTimeMillis();
106108

107-
log.debug("High priority request [{}] is waiting until permit is available.", requestId);
109+
log.debug(
110+
"High priority request [{}] is waiting until permit is available.",
111+
permitRequest.getRequestId());
108112

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

111115
final boolean granted =
112-
this.permitService.createPermitWithHighPriority(
113-
networkSegment, clientId, requestId, maxConcurrency);
116+
this.permitService.createPermit(networkSegment, permitRequest, maxConcurrency, true);
114117

115118
if (!granted) {
119+
120+
if (this.pauseWaitForHighPrioInMs > -1) {
121+
try {
122+
TimeUnit.MILLISECONDS.sleep(this.pauseWaitForHighPrioInMs);
123+
} catch (final InterruptedException e) {
124+
Thread.currentThread().interrupt();
125+
}
126+
}
127+
116128
continue;
117129
}
118130

119-
log.debug("High priority request [{}] is granted a permit.", requestId);
131+
log.debug("High priority request [{}] is granted a permit.", permitRequest.getRequestId());
120132
return true;
121133
}
122134

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/config/RedisConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class RedisConfig {
6161
@Value("${redis.connection.pool-size:64}")
6262
private int redisConnectionPoolSize;
6363

64-
@Bean
64+
@Bean(destroyMethod = "shutdown")
6565
public RedissonClient redissonClient(final Config redissonConfig) {
6666
this.installJCAProvider();
6767
return Redisson.create(redissonConfig);

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/model/Permit.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
package org.opensmartgridplatform.throttling.model;
66

7-
public record Permit(NetworkSegment networkSegment, int clientId, int requestId) {}
7+
public record Permit(NetworkSegment networkSegment, PermitRequest permitRequest) {}

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/model/PermitKey.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class PermitKey {
1313

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

1718
private short throttlingConfigID;
1819
private int baseTransceiverStationId;
@@ -42,6 +43,14 @@ public String lockId() {
4243
this.asString(this.cellId));
4344
}
4445

46+
public String lobby() {
47+
return String.format(
48+
LOBBY_FORMAT,
49+
this.asString(this.throttlingConfigID),
50+
this.asString(this.baseTransceiverStationId),
51+
this.asString(this.cellId));
52+
}
53+
4554
private String asString(final int value) {
4655
return this.asString(value, false);
4756
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-FileCopyrightText: Copyright Contributors to the GXF project
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package org.opensmartgridplatform.throttling.model;
6+
7+
import java.util.UUID;
8+
import lombok.EqualsAndHashCode;
9+
import lombok.Getter;
10+
11+
@EqualsAndHashCode
12+
@Getter
13+
public class PermitRequest {
14+
final int clientId;
15+
final int requestId;
16+
final UUID uuid;
17+
18+
public PermitRequest(final int clientId, final int requestId) {
19+
this.clientId = clientId;
20+
this.requestId = requestId;
21+
this.uuid = UUID.randomUUID();
22+
}
23+
}

osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/services/PermitService.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@
77
import java.util.Optional;
88
import org.opensmartgridplatform.throttling.model.NetworkSegment;
99
import org.opensmartgridplatform.throttling.model.Permit;
10+
import org.opensmartgridplatform.throttling.model.PermitRequest;
1011

1112
public interface PermitService {
1213

1314
boolean createPermit(
14-
final NetworkSegment networkSegment,
15-
final int clientId,
16-
final int requestId,
17-
final int maxConcurrentRequests);
15+
NetworkSegment networkSegment,
16+
PermitRequest permitRequest,
17+
int maxConcurrentRequests,
18+
boolean highPrioRequest);
1819

19-
boolean createPermitWithHighPriority(
20-
final NetworkSegment networkSegment,
21-
final int clientId,
22-
final int requestId,
23-
final int maxConcurrentRequests);
24-
25-
boolean removePermit(
26-
final NetworkSegment networkSegment, final int clientId, final int requestId);
20+
boolean removePermit(NetworkSegment networkSegment, PermitRequest permitRequest);
2721

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

0 commit comments

Comments
 (0)