UNPKG

@grouparoo/core

Version:
137 lines (136 loc) 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImportRecordProperties = void 0; const retryableTask_1 = require("../../classes/tasks/retryableTask"); const GrouparooRecord_1 = require("../../models/GrouparooRecord"); const RecordProperty_1 = require("../../models/RecordProperty"); const sequelize_1 = require("sequelize"); const actionhero_1 = require("actionhero"); const cls_1 = require("../../modules/cls"); const property_1 = require("../../modules/ops/property"); const import_1 = require("../../modules/ops/import"); const record_1 = require("../../modules/ops/record"); const apiData_1 = require("../../modules/apiData"); const propertiesCache_1 = require("../../modules/caches/propertiesCache"); const sourcesCache_1 = require("../../modules/caches/sourcesCache"); class ImportRecordProperties extends retryableTask_1.RetryableTask { constructor() { super(...arguments); this.name = "recordProperty:importRecordProperties"; this.description = "Import the GrouparooRecord Properties for a Property"; this.frequency = 0; this.queue = "recordProperties"; this.inputs = { recordIds: { required: true, formatter: apiData_1.APIData.ensureArray }, propertyIds: { required: true, formatter: apiData_1.APIData.ensureArray }, }; } async runWithinTransaction({ recordIds, propertyIds, }) { const records = await GrouparooRecord_1.GrouparooRecord.findAll({ where: { id: { [sequelize_1.Op.in]: recordIds } }, include: RecordProperty_1.RecordProperty, }); if (records.length === 0) return; const allProperties = await propertiesCache_1.PropertiesCache.findAllWithCache(undefined, "ready"); const properties = allProperties.filter((p) => propertyIds.includes(p.id)); if (properties.length === 0) return; const sourceIds = properties .map((p) => p.sourceId) .filter((v, i, a) => a.indexOf(v) === i); if (sourceIds.length > 1) { throw new Error(`More than one source for properties ${propertyIds.join(", ")}`); } const source = await sourcesCache_1.SourcesCache.findOneWithCache(properties[0].sourceId); const recordsToImport = []; const recordsNotReady = []; const dependencies = {}; for (const property of properties) { dependencies[property.id] = await property_1.PropertyOps.dependencies(property); } for (const record of records) { let mode = "ready"; // all already (wrongly) ready? if (record.recordProperties.filter((p) => p.state === "ready").length === record.recordProperties.length) { mode = "notReady"; } for (const property of properties) { // dependencies are not ready dependencies[property.id] .filter((dep) => !propertyIds.includes(dep.id)) .forEach((dep) => { var _a; if (((_a = record.recordProperties.find((p) => p.propertyId === dep.id)) === null || _a === void 0 ? void 0 : _a.state) !== "ready") { mode = "notReady"; } }); } switch (mode) { case "ready": recordsToImport.push(record); break; case "notReady": recordsNotReady.push(record); break; } } if (recordsNotReady.length > 0) { await RecordProperty_1.RecordProperty.update({ startedAt: import_1.ImportOps.retryStartedAt() }, { where: { propertyId: { [sequelize_1.Op.in]: properties.map((p) => p.id) }, recordId: { [sequelize_1.Op.in]: recordsNotReady.map((p) => p.id), }, state: "pending", }, }); } if (recordsToImport.length === 0) return; try { const propertyValuesBatch = await source.importRecordProperties(recordsToImport, properties); const orderedRecords = []; const orderedHashes = []; for (const recordId in propertyValuesBatch) { const record = recordsToImport.find((p) => p.id === recordId); orderedRecords.push(record); orderedHashes.push(propertyValuesBatch[recordId]); } if (orderedRecords.length > 0) { await record_1.RecordOps.addOrUpdateProperties(orderedRecords, orderedHashes, false // we are disabling the record lock here because the transaction will be saved out-of-band from the lock check ); } // update the properties that got no data back await RecordProperty_1.RecordProperty.update({ state: "ready", rawValue: null, stateChangedAt: new Date(), confirmedAt: new Date(), startedAt: null, }, { where: { propertyId: { [sequelize_1.Op.in]: properties.map((p) => p.id) }, recordId: { [sequelize_1.Op.in]: recordsToImport.map((p) => p.id), }, state: "pending", }, }); } catch (error) { // if something goes wrong with the batch import, fall-back to per-record/property imports for (const record of recordsToImport) { for (const property of properties) { await cls_1.CLS.enqueueTask("recordProperty:importRecordProperty", { recordId: record.id, propertyId: property.id, }); } } (0, actionhero_1.log)(error.stack, "error"); } } } exports.ImportRecordProperties = ImportRecordProperties;