All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.projectnessie.nessie.tasks.api.TaskState Maven / Gradle / Ivy

/*
 * Copyright (C) 2024 Dremio
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.projectnessie.nessie.tasks.api;

import static com.google.common.base.Preconditions.checkState;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import java.time.Instant;
import org.immutables.value.Value;
import org.projectnessie.nessie.tasks.api.JacksonSerializers.InstantAsLongDeserializer;
import org.projectnessie.nessie.tasks.api.JacksonSerializers.InstantAsLongSerializer;

/** Task state as a value object. */
@Value.Immutable
@JsonSerialize(as = ImmutableTaskState.class)
@JsonDeserialize(as = ImmutableTaskState.class)
public interface TaskState {
  /** The current task status. */
  @Value.Parameter(order = 1)
  TaskStatus status();

  /**
   * Represents the earliest timestamp when a retryable error can be retried or the value/state of a
   * running task can be refreshed. Only valid for {@link TaskStatus#RUNNING RUNNING} and {@link
   * TaskStatus#ERROR_RETRY ERROR_RETRY}.
   */
  @Value.Parameter(order = 2)
  @Nullable
  @JsonInclude(JsonInclude.Include.NON_NULL)
  @JsonDeserialize(using = InstantAsLongDeserializer.class)
  @JsonSerialize(using = InstantAsLongSerializer.class)
  Instant retryNotBefore();

  /**
   * Represents the earliest timestamp when a task service can assume that a {@link
   * TaskStatus#RUNNING RUNNING} task is lost and should be re-started. Only valid for {@link
   * TaskStatus#RUNNING RUNNING}.
   */
  @Value.Parameter(order = 3)
  @Nullable
  @JsonInclude(JsonInclude.Include.NON_NULL)
  @JsonDeserialize(using = InstantAsLongDeserializer.class)
  @JsonSerialize(using = InstantAsLongSerializer.class)
  Instant lostNotBefore();

  /**
   * Represents an error message. Only valid for {@link TaskStatus#FAILURE FAILURE} and {@link
   * TaskStatus#ERROR_RETRY ERROR_RETRY}.
   */
  @Value.Parameter(order = 4)
  @Nullable
  @JsonInclude(JsonInclude.Include.NON_NULL)
  String message();

  /**
   * An error code associated with this task state. Error codes are machine-readable representations
   * of failures and are meant to be interpreted by the {@link TaskBehavior} implementation that
   * manages the related task.
   *
   * 

On the other hand, the value of {@link #message()} is meant to be interpreted by humans. * *

Storing error codes in {@link TaskState} is intended to allow reporting task errors / * exceptions to the caller the same way whether the task fails for the first time in the server * that executed it, or it is reloaded from storage in another server. * * @see TaskBehavior#stateAsException(TaskObj) */ @Value.Parameter(order = 5) @Nullable @JsonInclude(JsonInclude.Include.NON_NULL) String errorCode(); TaskState SUCCESS = ImmutableTaskState.of(TaskStatus.SUCCESS, null, null, null, null); static TaskState successState() { return SUCCESS; } static TaskState runningState(@Nonnull Instant retryNotBefore, @Nonnull Instant lostNotBefore) { return ImmutableTaskState.of(TaskStatus.RUNNING, retryNotBefore, lostNotBefore, null, null); } static TaskState retryableErrorState( @Nonnull Instant retryNotBefore, @Nonnull String message, @Nonnull String errorCode) { return ImmutableTaskState.of(TaskStatus.ERROR_RETRY, retryNotBefore, null, message, errorCode); } static TaskState failureState(@Nonnull String message, String errorCode) { return ImmutableTaskState.of(TaskStatus.FAILURE, null, null, message, errorCode); } static TaskState taskState( TaskStatus taskStatus, Instant retryNotBefore, Instant lostNotBefore, String message, String errorCode) { return ImmutableTaskState.of(taskStatus, retryNotBefore, lostNotBefore, message, errorCode); } @Value.Check default void check() { switch (status()) { case SUCCESS: checkState(retryNotBefore() == null, "retryNotBefore must be null for SUCCESS"); checkState(lostNotBefore() == null, "retryNotBefore must be null for SUCCESS"); break; case FAILURE: checkState(retryNotBefore() == null, "retryNotBefore must be null for FAILURE"); checkState(lostNotBefore() == null, "lostNotBefore must be null for FAILURE"); checkState(message() != null, "message must not be null for FAILURE"); break; case RUNNING: checkState(retryNotBefore() != null, "retryNotBefore must not be null for RUNNING"); checkState(lostNotBefore() != null, "lostNotBefore must not be null for RUNNING"); break; case ERROR_RETRY: checkState(retryNotBefore() != null, "retryNotBefore must not be null for ERROR_RETRY"); checkState(lostNotBefore() == null, "lostNotBefore must be null for ERROR_RETRY"); checkState(message() != null, "message must not be null for ERROR_RETRY"); break; default: throw new IllegalStateException("Unknown task status " + status()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy