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;
}
Aggregations