Search in sources :

Example 1 with RunRecordDetailWithExistingStatus

use of io.cdap.cdap.internal.app.store.RunRecordDetailWithExistingStatus in project cdap by caskdata.

the class ProgramNotificationSubscriberService method handleProgramCompletion.

/**
 * Handles a program completion notification.
 *
 * @param appMetadataStore the {@link AppMetadataStore} to write the status to
 * @param programHeartbeatTable the {@link ProgramHeartbeatTable} to write the status to
 * @param programRunId the program run of the completed program
 * @param programRunStatus the status of the completion
 * @param notification the {@link Notification} that carries information about the program completion
 * @param sourceId the source message id of the notification
 * @param runnables a {@link List} adding {@link Runnable} to be executed after event handling is completed
 * @return a {@link RunRecordDetail} that carries the result of updates to {@link AppMetadataStore}. If there
 *         is no update, {@code null} will be returned
 * @throws Exception if failed to update program status
 */
@Nullable
private RunRecordDetail handleProgramCompletion(AppMetadataStore appMetadataStore, ProgramHeartbeatTable programHeartbeatTable, ProgramRunId programRunId, ProgramRunStatus programRunStatus, Notification notification, byte[] sourceId, List<Runnable> runnables) throws Exception {
    Map<String, String> properties = notification.getProperties();
    long endTimeSecs = getTimeSeconds(properties, ProgramOptionConstants.END_TIME);
    if (endTimeSecs == -1) {
        LOG.warn("Ignore program {} notification for program {} without end time specified, {}", programRunStatus.name().toLowerCase(), programRunId, notification);
        return null;
    }
    BasicThrowable failureCause = decodeBasicThrowable(properties.get(ProgramOptionConstants.PROGRAM_ERROR));
    // If there is any states missing, it will be handled here.
    if (programRunId.getType() == ProgramType.WORKFLOW) {
        processWorkflowOnStop(appMetadataStore, programHeartbeatTable, programRunId, programRunStatus, notification, sourceId, runnables);
    }
    RunRecordDetailWithExistingStatus recordedRunRecord = appMetadataStore.recordProgramStop(programRunId, endTimeSecs, programRunStatus, failureCause, sourceId);
    if (recordedRunRecord != null) {
        writeToHeartBeatTable(recordedRunRecord, endTimeSecs, programHeartbeatTable);
        getEmitMetricsRunnable(programRunId, recordedRunRecord, STATUS_METRICS_NAME.get(programRunStatus), recordedRunRecord.getExistingStatus()).ifPresent(runnables::add);
        // emit program run time metric.
        long runTime = endTimeSecs - RunIds.getTime(programRunId.getRun(), TimeUnit.SECONDS);
        SystemArguments.getProfileIdFromArgs(programRunId.getNamespaceId(), recordedRunRecord.getSystemArgs()).ifPresent(profileId -> emitRunTimeMetric(programRunId, programRunStatus, runTime));
        runnables.add(() -> {
            programCompletionNotifiers.forEach(notifier -> notifier.onProgramCompleted(programRunId, recordedRunRecord.getStatus()));
            runRecordMonitorService.removeRequest(programRunId, true);
        });
    }
    return recordedRunRecord;
}
Also used : RunRecordDetailWithExistingStatus(io.cdap.cdap.internal.app.store.RunRecordDetailWithExistingStatus) BasicThrowable(io.cdap.cdap.proto.BasicThrowable) Nullable(javax.annotation.Nullable)

Aggregations

RunRecordDetailWithExistingStatus (io.cdap.cdap.internal.app.store.RunRecordDetailWithExistingStatus)1 BasicThrowable (io.cdap.cdap.proto.BasicThrowable)1 Nullable (javax.annotation.Nullable)1