@grouparoo/core
Version:
The Grouparoo Core
211 lines (210 loc) • 8.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScheduleOps = void 0;
const Run_1 = require("../../models/Run");
const Option_1 = require("../../models/Option");
const Mapping_1 = require("../../models/Mapping");
const actionhero_1 = require("actionhero");
const propertiesCache_1 = require("../caches/propertiesCache");
var ScheduleOps;
(function (ScheduleOps) {
async function run(schedule, run) {
const options = await schedule.getOptions();
const scheduleFilters = await schedule.getFilters();
const source = await schedule.$get("source", {
scope: null,
include: [Option_1.Option, Mapping_1.Mapping],
});
const app = await source.$get("app", { include: [Option_1.Option], scope: null });
const properties = await propertiesCache_1.PropertiesCache.findAllWithCache(source.modelId, "ready");
const { pluginConnection } = await source.getPlugin();
const method = pluginConnection.methods.importRecords;
if (!method) {
throw new Error(`cannot find an import method for app type ${app.type}`);
}
const appOptions = await app.getOptions();
const sourceOptions = await source.getOptions();
const sourceMapping = await source.getMapping();
await app.validateOptions(appOptions);
const connection = await app.getConnection();
await source.validateOptions(sourceOptions);
const limit = actionhero_1.config.batchSize.imports;
const sourceOffset = run.sourceOffset || 0;
let highWaterMark = {};
if (run.highWaterMark && Object.keys(run.highWaterMark).length > 0) {
highWaterMark = run.highWaterMark;
}
else if (schedule.incremental) {
const previousRun = await run.previousRun();
if (previousRun === null || previousRun === void 0 ? void 0 : previousRun.highWaterMark)
highWaterMark = previousRun.highWaterMark;
}
let importsCount = 0;
let nextHighWaterMark;
let nextSourceOffset;
try {
const response = await method({
schedule,
scheduleId: schedule.id,
scheduleOptions: options,
scheduleFilters,
connection,
app,
appId: app.id,
appOptions,
source,
sourceId: source.id,
sourceOptions,
sourceMapping,
properties,
run,
runId: run.id,
limit,
highWaterMark,
sourceOffset,
});
importsCount = response.importsCount || 0;
nextHighWaterMark = response.highWaterMark || {};
nextSourceOffset = response.sourceOffset || 0;
}
catch (error) {
(0, actionhero_1.log)(`failed run ${run.id} for schedule ${schedule.id}: ${error}`, "error", error);
run.error = error.stack || error.toString();
await run.save();
}
return {
importsCount,
highWaterMark: schedule.incremental ? nextHighWaterMark : {},
sourceOffset: nextSourceOffset,
};
}
ScheduleOps.run = run;
/**
* Load the options for this schedule from the plugin
*/
async function pluginOptions(schedule) {
const source = await schedule.$get("source", {
scope: null,
include: [Option_1.Option, Mapping_1.Mapping],
});
const { pluginConnection } = await source.getPlugin();
const response = [];
if (!pluginConnection) {
throw new Error(`cannot find a pluginConnection for type ${source.type}`);
}
if (!pluginConnection.methods.scheduleOptions)
return response;
const app = await source.$get("app", { scope: null, include: [Option_1.Option] });
const connection = await app.getConnection();
const appOptions = await app.getOptions();
const sourceOptions = await source.getOptions();
const sourceMapping = await source.getMapping();
const properties = await propertiesCache_1.PropertiesCache.findAllWithCache(source.modelId, "ready");
const scheduleOptions = await schedule.getOptions();
const scheduleOptionOptions = await pluginConnection.methods.scheduleOptions({
schedule,
scheduleId: schedule.id,
scheduleOptions,
});
for (const i in scheduleOptionOptions) {
const opt = scheduleOptionOptions[i];
const options = await opt.options({
connection,
app,
appId: app.id,
appOptions,
source,
sourceId: source.id,
sourceOptions,
sourceMapping,
properties,
});
response.push({
key: opt.key,
description: opt.description,
required: opt.required,
type: opt.type,
options,
});
}
return response;
}
ScheduleOps.pluginOptions = pluginOptions;
/**
* Determine the percentage complete for this run
*/
async function runPercentComplete(schedule, run) {
const source = await schedule.$get("source", {
scope: null,
include: [Option_1.Option, Mapping_1.Mapping],
});
const { pluginConnection } = await source.getPlugin();
const method = pluginConnection.methods.sourceRunPercentComplete;
if (!method)
return 0;
const app = await source.$get("app", { scope: null, include: [Option_1.Option] });
const appOptions = await app.getOptions();
const sourceOptions = await source.getOptions();
const sourceMapping = await source.getMapping();
const scheduleOptions = await schedule.getOptions();
const scheduleFilters = await schedule.getFilters();
// In this case, we want to us the highWaterMark from the previous run, not this run's, as it will be moving over the live of the run
let highWaterMark = {};
const previousRun = await run.previousRun();
if (previousRun === null || previousRun === void 0 ? void 0 : previousRun.highWaterMark) {
highWaterMark = previousRun.highWaterMark;
}
return method({
connection: await app.getConnection(),
app,
appId: app.id,
appOptions,
source,
sourceId: source.id,
sourceOptions,
sourceMapping,
schedule,
scheduleId: schedule.id,
scheduleOptions,
scheduleFilters,
highWaterMark,
run,
runId: run.id,
});
}
ScheduleOps.runPercentComplete = runPercentComplete;
/**
* Determine if it is time to run
*/
async function shouldRun(schedule, options = {}) {
var _a, _b;
const ignoreDeltas = (_a = options.ignoreDeltas) !== null && _a !== void 0 ? _a : false;
const runIfNotRecurring = (_b = options.runIfNotRecurring) !== null && _b !== void 0 ? _b : false;
if (schedule.state !== "ready")
return false;
if (!runIfNotRecurring && schedule.recurring === false)
return false;
const runningRuns = await Run_1.Run.count({
where: {
creatorId: schedule.id,
creatorType: "schedule",
state: "running",
},
});
if (runningRuns > 0)
return false;
const lastCompleteRun = await Run_1.Run.scope(null).findOne({
where: {
creatorId: schedule.id,
creatorType: "schedule",
state: "complete",
},
order: [["completedAt", "desc"]],
});
if (!lastCompleteRun)
return true;
const delta = new Date().getTime() - lastCompleteRun.completedAt.getTime();
return ignoreDeltas ? true : delta > schedule.recurringFrequency;
}
ScheduleOps.shouldRun = shouldRun;
})(ScheduleOps = exports.ScheduleOps || (exports.ScheduleOps = {}));