ai.grakn.engine.tasks.manager.TaskState.java Source code

Java tutorial

Introduction

Here is the source code for ai.grakn.engine.tasks.manager.TaskState.java

Source

/*
 * Grakn - A Distributed Semantic Database
 * Copyright (C) 2016  Grakn Labs Limited
 *
 * Grakn is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Grakn is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Grakn. If not, see <http://www.gnu.org/licenses/gpl.txt>.
 */

package ai.grakn.engine.tasks.manager;

import ai.grakn.engine.TaskId;
import ai.grakn.engine.TaskStatus;
import static ai.grakn.engine.TaskStatus.COMPLETED;
import static ai.grakn.engine.TaskStatus.CREATED;
import static ai.grakn.engine.TaskStatus.FAILED;
import static ai.grakn.engine.TaskStatus.RUNNING;
import static ai.grakn.engine.TaskStatus.SCHEDULED;
import static ai.grakn.engine.TaskStatus.STOPPED;
import ai.grakn.engine.tasks.BackgroundTask;
import ai.grakn.engine.util.EngineID;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.Instant;
import static java.time.Instant.now;
import static org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace;

/**
 * Internal task state model used to keep track of scheduled tasks.
 * TODO: make immutable, fix json serialisation/deserialisation
 *
 * @author Denis Lobanov
 */
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TaskState implements Serializable {

    private static final long serialVersionUID = -7301340972479426653L;

    /**
     * The priority of the task which decides which queue the task should go into
     */
    public enum Priority {
        LOW, HIGH;

        public String queue() {
            return name() + "-priority-queue";
        }
    }

    /**
     * Id of this task.
     */
    private final String taskId;
    /**
     * The priority of the task which decides which queue the task should go into
     */
    private final Priority priority;
    /**
     * Task status, @see TaskStatus.
     */
    private TaskStatus status;
    /**
     * Time when task status was last updated.
     */
    private Instant statusChangeTime;
    /**
     * Name of Class implementing the BackgroundTask interface that should be executed when task is run.
     */
    private final String taskClassName;
    /**
     * String identifying who created this task.
     */
    private final String creator;
    /**
     * String identifying which engine instance is executing this task, set when task is scheduled.
     */
    private EngineID engineID;
    /**
     * Schedule for when this task should execute
     */
    private TaskSchedule schedule;
    /**
     * Used to store any executing failures for the given task.
     */
    private String stackTrace;
    private String exception;
    /**
     * Used to store a task checkpoint allowing it to resume from the same point of execution as at the time of the checkpoint.
     */
    private TaskCheckpoint taskCheckpoint;

    public static TaskState of(Class<?> taskClass, String creator, TaskSchedule schedule, Priority priority) {
        return new TaskState(taskClass, creator, schedule, TaskId.generate(), priority);
    }

    public static TaskState of(TaskId id) {
        return new TaskState(null, null, null, id, null);
    }

    @JsonCreator
    public TaskState(@JsonProperty("taskClass") Class<?> taskClass, @JsonProperty("creator") String creator,
            @JsonProperty("schedule") TaskSchedule schedule, @JsonProperty("id") TaskId id,
            @JsonProperty("priority") Priority priority) {
        this.status = CREATED;
        this.statusChangeTime = now();
        this.taskClassName = taskClass != null ? taskClass.getName() : null;
        this.creator = creator;
        this.schedule = schedule;
        this.taskId = id.getValue();
        this.priority = priority;
    }

    private TaskState(TaskState taskState) {
        this.taskId = taskState.taskId;
        this.status = taskState.status;
        this.statusChangeTime = taskState.statusChangeTime;
        this.taskClassName = taskState.taskClassName;
        this.creator = taskState.creator;
        this.engineID = taskState.engineID;
        this.schedule = taskState.schedule;
        this.stackTrace = taskState.stackTrace;
        this.exception = taskState.exception;
        this.taskCheckpoint = taskState.taskCheckpoint;
        this.priority = taskState.priority;
    }

    @JsonProperty("id")
    public TaskId getId() {
        return TaskId.of(taskId);
    }

    public TaskState markRunning(EngineID engineID) {
        this.status = RUNNING;
        this.engineID = engineID;
        this.statusChangeTime = now();

        return this;
    }

    public TaskState markCompleted() {
        this.status = COMPLETED;
        this.statusChangeTime = now();

        // Clearing out any not relevant information
        this.taskCheckpoint = null;

        return this;
    }

    public TaskState markScheduled() {
        this.status = SCHEDULED;
        this.statusChangeTime = now();

        return this;
    }

    public TaskState markStopped() {
        this.status = STOPPED;
        this.statusChangeTime = now();

        return this;
    }

    public TaskState markFailed(Throwable exception) {
        this.status = FAILED;
        this.exception = exception.getClass().getName();
        this.stackTrace = getFullStackTrace(exception);
        this.statusChangeTime = now();

        // We want to keep the configuration and checkpoint here
        // It's useful to debug failed states

        return this;
    }

    public TaskStatus status() {
        return status;
    }

    public Instant statusChangeTime() {
        return statusChangeTime;
    }

    public Class<? extends BackgroundTask> taskClass() {
        try {
            return (Class<? extends BackgroundTask>) Class.forName(taskClassName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public String creator() {
        return creator;
    }

    @JsonProperty("creator")
    public String getCreator() {
        return creator;
    }

    public EngineID engineID() {
        return engineID;
    }

    public TaskSchedule schedule() {
        return schedule;
    }

    @JsonProperty("schedule")
    public TaskSchedule getSchedule() {
        return schedule;
    }

    public TaskState schedule(TaskSchedule schedule) {
        this.schedule = schedule;
        return this;
    }

    public String stackTrace() {
        return stackTrace;
    }

    public String exception() {
        return exception;
    }

    public TaskState checkpoint(TaskCheckpoint taskCheckpoint) {
        this.taskCheckpoint = taskCheckpoint;
        return this;
    }

    public Priority priority() {
        return priority;
    }

    public TaskCheckpoint checkpoint() {
        return taskCheckpoint;
    }

    public TaskState copy() {
        return new TaskState(this);
    }

    @JsonProperty("serialVersionUID")
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    @JsonProperty("priority")
    public Priority getPriority() {
        return priority;
    }

    @JsonProperty("status")
    public TaskStatus getStatus() {
        return status;
    }

    @JsonProperty("taskClassName")
    public String getTaskClassName() {
        return taskClassName;
    }

    @JsonProperty("engineId")
    public EngineID getEngineID() {
        return engineID;
    }

    @JsonProperty("taskCheckpoint")
    public TaskCheckpoint getTaskCheckpoint() {
        return taskCheckpoint;
    }

    @Override
    public String toString() {
        return "TaskState(" + taskClass().getSimpleName() + ", \"" + getId() + "\").status(" + status() + ")";
    }
}