diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java index f4003f771e3..9a14d6e7b07 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java @@ -120,11 +120,6 @@ public boolean releasePermit( final AtomicInteger permitCounter = this.getPermitCounter(baseTransceiverStationId, cellId); - // Notify that permit is released - synchronized (permitCounter) { - permitCounter.notifyAll(); - } - final int numberOfPermitsIfReleased = permitCounter.decrementAndGet(); if (numberOfPermitsIfReleased < 0) { permitCounter.incrementAndGet(); @@ -134,9 +129,20 @@ public boolean releasePermit( this.permitRepository.releasePermit( throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + if (this.useHighPrioPool()) { + // Notify that permit is released + synchronized (permitCounter) { + permitCounter.notifyAll(); + } + } + return numberOfReleasedPermits == 1; } + private boolean useHighPrioPool() { + return this.maxWaitForHighPrioInMs != 0; + } + private boolean isPermitAvailable( final int baseTransceiverStationId, final int cellId, @@ -148,6 +154,10 @@ private boolean isPermitAvailable( if (numberOfPermitsIfGranted > maxConcurrency) { permitCounter.decrementAndGet(); + if (!this.useHighPrioPool()) { + return false; + } + if (priority <= MessagePriorityEnum.DEFAULT.getPriority()) { return false; } diff --git a/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties b/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties index fdc03907db6..88ffc5ac748 100644 --- a/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties +++ b/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties @@ -31,7 +31,9 @@ scheduling.task.cleanup.permits.cron.expression=0 0/30 * * * ? # Releasing expired permits will happen in batches of the following size. cleanup.permits.batch.size=100 -max.wait.for.high.prio.in.ms=5000 +#max.wait.for.high.prio.in.ms=5000 +# For now we disable this high prio pool by default +max.wait.for.high.prio.in.ms=0 # The task to reset in memory counters with db state is executed by cron expression. scheduling.task.reinitialize.state.cron.expression=30 0/30 * * * ? diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java index cd39cf64d3b..a7992f11eea 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java @@ -6,13 +6,19 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.List; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import org.assertj.core.util.Lists; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensmartgridplatform.throttling.repositories.PermitRepository; @@ -130,6 +136,78 @@ void testInitializeDelete() { assertThat(this.permitsPerNetworkSegment.permitsPerNetworkSegment()).isEmpty(); } + @ParameterizedTest + @ValueSource(ints = {0, 2000}) + void testHighPrioPoolTime(final int maxWaitForHighPrio) { + this.permitsPerNetworkSegment = + new PermitsPerNetworkSegment(this.permitRepository, maxWaitForHighPrio); + + final int btsId = 1; + final int cellId = 2; + final int numberOfPermits = 3; + final short throttlingConfigId = Integer.valueOf(1).shortValue(); + final int clientId = 4; + final int requestId = 5; + final int priority = 6; + final int maxConcurrency = numberOfPermits; + + this.preparePermits(btsId, cellId, numberOfPermits, throttlingConfigId); + + this.permitsPerNetworkSegment.initialize(throttlingConfigId); + + final long start = System.currentTimeMillis(); + final boolean permitGranted = + this.permitsPerNetworkSegment.requestPermit( + throttlingConfigId, clientId, btsId, cellId, requestId, priority, maxConcurrency); + assertThat(permitGranted).isFalse(); + assertThat(System.currentTimeMillis() - start).isGreaterThanOrEqualTo(maxWaitForHighPrio); + + verify(this.permitRepository, never()) + .grantPermit(throttlingConfigId, clientId, btsId, cellId, requestId); + } + + @Test + void testHighPrioPool() { + final int maxWaitForHighPrio = 10000; + final int waitBeforeRelease = 1000; + this.permitsPerNetworkSegment = + new PermitsPerNetworkSegment(this.permitRepository, maxWaitForHighPrio); + + final int btsId = 1; + final int cellId = 2; + final int numberOfPermits = 3; + final short throttlingConfigId = Integer.valueOf(1).shortValue(); + final int clientId = 4; + final int requestId = 5; + final int priority = 6; + final int maxConcurrency = numberOfPermits; + + this.preparePermits(btsId, cellId, numberOfPermits, throttlingConfigId); + + when(this.permitRepository.grantPermit(throttlingConfigId, clientId, btsId, cellId, requestId)) + .thenReturn(true); + + this.permitsPerNetworkSegment.initialize(throttlingConfigId); + + final long start = System.currentTimeMillis(); + + final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); + executor.schedule( + () -> { + PermitsPerNetworkSegmentTest.this.permitsPerNetworkSegment.releasePermit( + throttlingConfigId, clientId, btsId, cellId, requestId); + }, + waitBeforeRelease, + TimeUnit.MILLISECONDS); + + final boolean permitGranted = + this.permitsPerNetworkSegment.requestPermit( + throttlingConfigId, clientId, btsId, cellId, requestId, priority, maxConcurrency); + assertThat(permitGranted).isTrue(); + assertThat((int) (System.currentTimeMillis() - start)) + .isBetween(waitBeforeRelease, maxWaitForHighPrio); + } + private void preparePermits( final int btsId, final int cellId,