use of io.pravega.controller.task.EventHelper in project pravega by pravega.
the class StreamMetadataTasks method deleteStream.
public CompletableFuture<DeleteStreamStatus.Status> deleteStream(final String scope, final String stream, final OperationContext context) {
Preconditions.checkNotNull(context, "Operation Context is null");
// We can delete streams only if they are sealed. However, for partially created streams, they could be in different
// stages of partial creation and we should be able to clean them up.
// Case 1: A partially created stream may just have some initial metadata created, in which case the Stream's state may not
// have been set up it may be present under the scope.
// In this case we can simply delete all metadata for the stream directly.
// Case 2: A partially created stream could be in state CREATING, in which case it would definitely have metadata created
// and possibly segments too. This requires same clean up as for a sealed stream - metadata + segments.
// So we will submit delete workflow.
long requestId = context.getRequestId();
return eventHelperFuture.thenCompose(eventHelper -> Futures.exceptionallyExpecting(streamMetadataStore.getState(scope, stream, false, context, executor), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, State.UNKNOWN).thenCompose(state -> {
if (State.SEALED.equals(state) || State.CREATING.equals(state)) {
return streamMetadataStore.getCreationTime(scope, stream, context, executor).thenApply(time -> new DeleteStreamEvent(scope, stream, requestId, time)).thenCompose(eventHelper::writeEvent).thenApply(x -> true);
} else if (State.UNKNOWN.equals(state)) {
// so we can simply delete the stream metadata which deletes stream from scope as well.
return streamMetadataStore.deleteStream(scope, stream, context, executor).exceptionally(e -> {
throw new CompletionException(e);
}).thenApply(v -> true);
} else {
// we cannot delete the stream. Return false from here.
return CompletableFuture.completedFuture(false);
}
}).thenCompose(result -> {
if (result) {
return eventHelper.checkDone(() -> isDeleted(scope, stream, context)).thenApply(x -> DeleteStreamStatus.Status.SUCCESS);
} else {
return CompletableFuture.completedFuture(DeleteStreamStatus.Status.STREAM_NOT_SEALED);
}
})).exceptionally(ex -> {
return handleDeleteStreamError(ex, requestId, NameUtils.getScopedStreamName(scope, stream));
});
}
use of io.pravega.controller.task.EventHelper in project pravega by pravega.
the class StreamMetadataTasks method manualScale.
/**
* Helper method to perform scale operation against an scale request.
* This method posts a request in the request stream and then starts the scale operation while
* tracking it's progress. Eventually, after scale completion, it sends a response to the caller.
*
* @param scope scope.
* @param stream stream name.
* @param segmentsToSeal segments to be sealed.
* @param newRanges key ranges for new segments.
* @param scaleTimestamp scaling time stamp.
* @param requestId request id
* @return returns the newly created segments.
*/
public CompletableFuture<ScaleResponse> manualScale(String scope, String stream, List<Long> segmentsToSeal, List<Map.Entry<Double, Double>> newRanges, long scaleTimestamp, long requestId) {
final OperationContext context = streamMetadataStore.createStreamContext(scope, stream, requestId);
ScaleOpEvent event = new ScaleOpEvent(scope, stream, segmentsToSeal, newRanges, true, scaleTimestamp, requestId);
return eventHelperFuture.thenCompose(eventHelper -> eventHelper.addIndexAndSubmitTask(event, () -> streamMetadataStore.submitScale(scope, stream, segmentsToSeal, new ArrayList<>(newRanges), scaleTimestamp, null, context, executor)).handle((startScaleResponse, e) -> {
ScaleResponse.Builder response = ScaleResponse.newBuilder();
if (e != null) {
Throwable cause = Exceptions.unwrap(e);
if (cause instanceof EpochTransitionOperationExceptions.PreConditionFailureException) {
response.setStatus(ScaleResponse.ScaleStreamStatus.PRECONDITION_FAILED);
} else {
log.error(requestId, "Scale for stream {}/{} failed with exception {}", scope, stream, cause);
response.setStatus(ScaleResponse.ScaleStreamStatus.FAILURE);
}
} else {
log.info(requestId, "scale for stream {}/{} started successfully", scope, stream);
response.setStatus(ScaleResponse.ScaleStreamStatus.STARTED);
response.addAllSegments(startScaleResponse.getObject().getNewSegmentsWithRange().entrySet().stream().map(segment -> convert(scope, stream, segment)).collect(Collectors.toList()));
response.setEpoch(startScaleResponse.getObject().getActiveEpoch());
}
return response.build();
}));
}
use of io.pravega.controller.task.EventHelper in project pravega by pravega.
the class StreamMetadataTasks method sealStream.
@VisibleForTesting
CompletableFuture<UpdateStreamStatus.Status> sealStream(String scope, String stream, OperationContext context, int retryCount) {
long requestId = context.getRequestId();
// 1. post event for seal.
SealStreamEvent event = new SealStreamEvent(scope, stream, requestId);
return eventHelperFuture.thenCompose(eventHelper -> eventHelper.addIndexAndSubmitTask(event, // 2. set state to sealing
() -> RetryHelper.withRetriesAsync(() -> streamMetadataStore.getVersionedState(scope, stream, context, executor).thenCompose(state -> {
if (state.getObject().equals(State.SEALED)) {
return CompletableFuture.completedFuture(state);
} else {
return streamMetadataStore.updateVersionedState(scope, stream, State.SEALING, state, context, executor);
}
}), RetryHelper.RETRYABLE_PREDICATE.or(e -> Exceptions.unwrap(e) instanceof StoreException.OperationNotAllowedException), retryCount, executor)).thenCompose(result -> {
if (result.getObject().equals(State.SEALED) || result.getObject().equals(State.SEALING)) {
return eventHelper.checkDone(() -> isSealed(scope, stream, context)).thenApply(x -> UpdateStreamStatus.Status.SUCCESS);
} else {
return CompletableFuture.completedFuture(UpdateStreamStatus.Status.FAILURE);
}
})).exceptionally(ex -> {
final String message = "Exception thrown in trying to notify sealed segments.";
return handleUpdateStreamError(ex, requestId, message, NameUtils.getScopedStreamName(scope, stream));
});
}
use of io.pravega.controller.task.EventHelper in project pravega by pravega.
the class StreamMetadataTasks method startTruncation.
public CompletableFuture<Boolean> startTruncation(String scope, String stream, Map<Long, Long> streamCut, OperationContext contextOpt) {
final OperationContext context = contextOpt != null ? contextOpt : streamMetadataStore.createStreamContext(scope, stream, ControllerService.nextRequestId());
long requestId = context.getRequestId();
return streamMetadataStore.getTruncationRecord(scope, stream, context, executor).thenCompose(property -> {
if (!property.getObject().isUpdating()) {
// 2. post event with new stream cut if no truncation is ongoing
return eventHelperFuture.thenCompose(eventHelper -> eventHelper.addIndexAndSubmitTask(new TruncateStreamEvent(scope, stream, requestId), // 3. start truncation by updating the metadata
() -> streamMetadataStore.startTruncation(scope, stream, streamCut, context, executor)).thenApply(x -> {
log.debug(requestId, "Started truncation request for stream {}/{}", scope, stream);
return true;
}));
} else {
log.error(requestId, "Another truncation in progress for {}/{}", scope, stream);
return CompletableFuture.completedFuture(false);
}
});
}
use of io.pravega.controller.task.EventHelper in project pravega by pravega.
the class ControllerServiceWithKVTableTest method setup.
@Before
public void setup() {
segmentHelperMock = SegmentHelperMock.getSegmentHelperMockForTables(executor);
streamStore = spy(getStore());
kvtStore = spy(getKVTStore());
BucketStore bucketStore = StreamStoreFactory.createZKBucketStore(PRAVEGA_ZK_CURATOR_RESOURCE.client, executor);
TaskMetadataStore taskMetadataStore = TaskStoreFactory.createZKStore(PRAVEGA_ZK_CURATOR_RESOURCE.client, executor);
connectionFactory = new SocketConnectionFactoryImpl(ClientConfig.builder().controllerURI(URI.create("tcp://localhost")).build());
GrpcAuthHelper disabledAuthHelper = GrpcAuthHelper.getDisabledAuthHelper();
StreamMetrics.initialize();
TransactionMetrics.initialize();
EventHelper helperMock = EventHelperMock.getEventHelperMock(executor, "host", ((AbstractStreamMetadataStore) streamStore).getHostTaskIndex());
streamMetadataTasks = new StreamMetadataTasks(streamStore, bucketStore, taskMetadataStore, segmentHelperMock, executor, "host", disabledAuthHelper, helperMock);
streamTransactionMetadataTasks = new StreamTransactionMetadataTasks(streamStore, segmentHelperMock, executor, "host", disabledAuthHelper);
kvtMetadataTasks = spy(new TableMetadataTasks(kvtStore, segmentHelperMock, executor, executor, "host", GrpcAuthHelper.getDisabledAuthHelper(), helperMock));
StreamRequestHandler streamRequestHandler = new StreamRequestHandler(new AutoScaleTask(streamMetadataTasks, streamStore, executor), new ScaleOperationTask(streamMetadataTasks, streamStore, executor), new UpdateStreamTask(streamMetadataTasks, streamStore, bucketStore, executor), new SealStreamTask(streamMetadataTasks, streamTransactionMetadataTasks, streamStore, executor), new DeleteStreamTask(streamMetadataTasks, streamStore, bucketStore, executor), new TruncateStreamTask(streamMetadataTasks, streamStore, executor), new CreateReaderGroupTask(streamMetadataTasks, streamStore, executor), new DeleteReaderGroupTask(streamMetadataTasks, streamStore, executor), new UpdateReaderGroupTask(streamMetadataTasks, streamStore, executor), streamStore, new DeleteScopeTask(streamMetadataTasks, streamStore, kvtStore, kvtMetadataTasks, executor), executor);
streamMetadataTasks.setRequestEventWriter(new ControllerEventStreamWriterMock(streamRequestHandler, executor));
consumer = new ControllerService(kvtStore, kvtMetadataTasks, streamStore, bucketStore, streamMetadataTasks, streamTransactionMetadataTasks, segmentHelperMock, executor, null, requestTracker);
}
Aggregations