IvmRefreshSummary.java
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.apache.doris.mtmv.ivm;
import org.apache.doris.job.extensions.mtmv.MTMVTask;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang3.StringUtils;
/**
* What the refresh tasks of an IVM MV have come to: consecutive failures, the latest success and failure, how the
* latest task refreshed the MV and how long it took, and how often a refresh fell back from the incremental path.
*
* <p>Kept on the MV rather than read from its task history, which holds only the latest
* max_persistence_task_count tasks. It is updated from each task result as the MV records it, on the Master and in
* the replay of the same journal record alike, and only from what that record carries, so a follower that takes
* over keeps the same summary.
*
* <p>A canceled task leaves it as it is: it neither succeeded nor failed, and it has no finish time to measure it
* by.
*/
public class IvmRefreshSummary {
// What the latest failure says, cut to this many characters.
public static final int MAX_ERROR_MESSAGE_LENGTH = 512;
// Failed tasks since the latest successful one.
@SerializedName("cf")
private int consecutiveFailures;
// Finish times in milliseconds, 0 when there has been none.
@SerializedName("lst")
private long lastSuccessTimeMs;
@SerializedName("lft")
private long lastFailureTimeMs;
// An IvmFailureReason or an IvmRefreshFailureStage; null for a failure recorded before the task carried it.
@SerializedName("lfr")
private String lastFailureReason;
@SerializedName("lem")
private String lastErrorMessage;
// Of the latest task that succeeded or failed.
@SerializedName("lrm")
private IvmRefreshMethod lastRefreshMethod;
@SerializedName("lrd")
private long lastRefreshDurationMs;
@SerializedName("fc")
private long fallbackCount;
@SerializedName("lfbr")
private String lastFallbackReason;
@SerializedName("lfbt")
private long lastFallbackTimeMs;
// Whether a refresh has ever succeeded: until one has, the MV has no baseline for the incremental refresh to
// keep up, and building it is not the incremental refresh falling back.
@SerializedName("s")
private boolean succeeded;
/** Takes in the result of a task, which has ended as SUCCESS, FAILED or CANCELED. */
public void update(MTMVTask task) {
switch (task.getStatus()) {
case SUCCESS:
consecutiveFailures = 0;
lastSuccessTimeMs = task.getFinishTimeMs();
succeeded = true;
break;
case FAILED:
consecutiveFailures++;
lastFailureTimeMs = task.getFinishTimeMs();
lastFailureReason = task.getIvmFailureReason();
lastErrorMessage = StringUtils.abbreviate(task.getErrMsg(), MAX_ERROR_MESSAGE_LENGTH);
break;
case CANCELED:
return;
default:
throw new IllegalStateException("A task result cannot be " + task.getStatus()
+ ", taskId=" + task.getTaskId());
}
lastRefreshMethod = task.getIvmRefreshMethod();
lastRefreshDurationMs = task.getFinishTimeMs() - task.getStartTimeMs();
if (task.isIvmFallback()) {
fallbackCount++;
lastFallbackReason = task.getIvmFallbackReason();
lastFallbackTimeMs = task.getFinishTimeMs();
}
}
public int getConsecutiveFailures() {
return consecutiveFailures;
}
public long getLastSuccessTimeMs() {
return lastSuccessTimeMs;
}
public long getLastFailureTimeMs() {
return lastFailureTimeMs;
}
public String getLastFailureReason() {
return lastFailureReason;
}
public String getLastErrorMessage() {
return lastErrorMessage;
}
public IvmRefreshMethod getLastRefreshMethod() {
return lastRefreshMethod;
}
public long getLastRefreshDurationMs() {
return lastRefreshDurationMs;
}
public long getFallbackCount() {
return fallbackCount;
}
public String getLastFallbackReason() {
return lastFallbackReason;
}
public long getLastFallbackTimeMs() {
return lastFallbackTimeMs;
}
public boolean hasSucceeded() {
return succeeded;
}
}