use of io.pravega.shared.controller.event.AutoScaleEvent in project pravega by pravega.
the class AutoScaleProcessor method triggerScaleDown.
private void triggerScaleDown(String streamSegmentName, boolean silent) {
if (initialized.get()) {
Pair<Long, Long> pair = cache.getIfPresent(streamSegmentName);
long lastRequestTs = 0;
if (pair != null && pair.getValue() != null) {
lastRequestTs = pair.getValue();
}
long timestamp = System.currentTimeMillis();
if (timestamp - lastRequestTs > configuration.getMuteDuration().toMillis()) {
log.info("sending request for scale down for {}", streamSegmentName);
Segment segment = Segment.fromScopedName(streamSegmentName);
AutoScaleEvent event = new AutoScaleEvent(segment.getScope(), segment.getStreamName(), segment.getSegmentNumber(), AutoScaleEvent.DOWN, timestamp, 0, silent);
writeRequest(event).thenAccept(x -> {
if (!silent) {
// mute only scale downs
cache.put(streamSegmentName, new ImmutablePair<>(0L, timestamp));
}
});
}
}
}
use of io.pravega.shared.controller.event.AutoScaleEvent in project pravega by pravega.
the class AutoScaleProcessor method triggerScaleUp.
private void triggerScaleUp(String streamSegmentName, int numOfSplits) {
if (initialized.get()) {
Pair<Long, Long> pair = cache.getIfPresent(streamSegmentName);
long lastRequestTs = 0;
if (pair != null && pair.getKey() != null) {
lastRequestTs = pair.getKey();
}
long timestamp = System.currentTimeMillis();
if (timestamp - lastRequestTs > configuration.getMuteDuration().toMillis()) {
log.info("sending request for scale up for {}", streamSegmentName);
Segment segment = Segment.fromScopedName(streamSegmentName);
AutoScaleEvent event = new AutoScaleEvent(segment.getScope(), segment.getStreamName(), segment.getSegmentNumber(), AutoScaleEvent.UP, timestamp, numOfSplits, false);
// Mute scale for timestamp for both scale up and down
writeRequest(event).thenAccept(x -> cache.put(streamSegmentName, new ImmutablePair<>(timestamp, timestamp)));
}
}
}
use of io.pravega.shared.controller.event.AutoScaleEvent in project pravega by pravega.
the class ScaleRequestHandlerTest method testScaleRequest.
@Test(timeout = 20000)
public void testScaleRequest() throws ExecutionException, InterruptedException {
AutoScaleTask requestHandler = new AutoScaleTask(streamMetadataTasks, streamStore, executor);
ScaleOperationTask scaleRequestHandler = new ScaleOperationTask(streamMetadataTasks, streamStore, executor);
StreamRequestHandler multiplexer = new StreamRequestHandler(requestHandler, scaleRequestHandler, null, null, null, null, executor);
// Send number of splits = 1
AutoScaleEvent request = new AutoScaleEvent(scope, stream, 2, AutoScaleEvent.UP, System.currentTimeMillis(), 1, false);
CompletableFuture<ScaleOpEvent> request1 = new CompletableFuture<>();
CompletableFuture<ScaleOpEvent> request2 = new CompletableFuture<>();
EventStreamWriter<ControllerEvent> writer = createWriter(x -> {
if (!request1.isDone()) {
final ArrayList<AbstractMap.SimpleEntry<Double, Double>> expected = new ArrayList<>();
double start = 2.0 / 3.0;
double end = 1.0;
double middle = (start + end) / 2;
expected.add(new AbstractMap.SimpleEntry<>(start, middle));
expected.add(new AbstractMap.SimpleEntry<>(middle, end));
checkRequest(request1, x, Lists.newArrayList(2), expected);
} else if (!request2.isDone()) {
final ArrayList<AbstractMap.SimpleEntry<Double, Double>> expected = new ArrayList<>();
double start = 2.0 / 3.0;
double end = 1.0;
expected.add(new AbstractMap.SimpleEntry<>(start, end));
checkRequest(request2, x, Lists.newArrayList(3, 4), expected);
}
});
when(clientFactory.createEventWriter(eq(Config.SCALE_STREAM_NAME), eq(new JavaSerializer<ControllerEvent>()), any())).thenReturn(writer);
assertTrue(Futures.await(multiplexer.process(request)));
assertTrue(Futures.await(request1));
assertTrue(Futures.await(multiplexer.process(request1.get())));
// verify that the event is posted successfully
List<Segment> activeSegments = streamStore.getActiveSegments(scope, stream, null, executor).get();
assertTrue(activeSegments.stream().noneMatch(z -> z.getNumber() == 2));
// verify that two splits are created even when we sent 1 as numOfSplits in AutoScaleEvent.
assertTrue(activeSegments.stream().anyMatch(z -> z.getNumber() == 3));
assertTrue(activeSegments.stream().anyMatch(z -> z.getNumber() == 4));
assertTrue(activeSegments.size() == 4);
request = new AutoScaleEvent(scope, stream, 4, AutoScaleEvent.DOWN, System.currentTimeMillis(), 0, false);
assertTrue(Futures.await(multiplexer.process(request)));
activeSegments = streamStore.getActiveSegments(scope, stream, null, executor).get();
assertTrue(activeSegments.stream().anyMatch(z -> z.getNumber() == 4));
assertTrue(activeSegments.size() == 4);
request = new AutoScaleEvent(scope, stream, 3, AutoScaleEvent.DOWN, System.currentTimeMillis(), 0, false);
assertTrue(Futures.await(multiplexer.process(request)));
assertTrue(Futures.await(request2));
assertTrue(Futures.await(multiplexer.process(request2.get())));
activeSegments = streamStore.getActiveSegments(scope, stream, null, executor).get();
assertTrue(activeSegments.stream().noneMatch(z -> z.getNumber() == 3));
assertTrue(activeSegments.stream().noneMatch(z -> z.getNumber() == 4));
assertTrue(activeSegments.stream().anyMatch(z -> z.getNumber() == 5));
assertTrue(activeSegments.size() == 3);
// make it throw a non retryable failure so that test does not wait for number of retries.
// This will bring down the test duration drastically because a retryable failure can keep retrying for few seconds.
// And if someone changes retry durations and number of attempts in retry helper, it will impact this test's running time.
// hence sending incorrect segmentsToSeal list which will result in a non retryable failure and this will fail immediately
assertFalse(Futures.await(multiplexer.process(new ScaleOpEvent(scope, stream, Lists.newArrayList(6), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.0, 1.0)), true, System.currentTimeMillis()))));
assertTrue(activeSegments.stream().noneMatch(z -> z.getNumber() == 3));
assertTrue(activeSegments.stream().noneMatch(z -> z.getNumber() == 4));
assertTrue(activeSegments.stream().anyMatch(z -> z.getNumber() == 5));
assertTrue(activeSegments.size() == 3);
assertFalse(Futures.await(multiplexer.process(new AbortEvent(scope, stream, 0, UUID.randomUUID()))));
}
Aggregations