UNPKG

@hotmeshio/hotmesh

Version:

Permanent-Memory Workflows & AI Agents

113 lines (112 loc) 4.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Cycle = void 0; const errors_1 = require("../../modules/errors"); const utils_1 = require("../../modules/utils"); const collator_1 = require("../collator"); const telemetry_1 = require("../telemetry"); const activity_1 = require("./activity"); class Cycle extends activity_1.Activity { constructor(config, data, metadata, hook, engine, context) { super(config, data, metadata, hook, engine, context); } //******** LEG 1 ENTRY ********// async process() { this.logger.debug('cycle-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid, }); let telemetry; try { await this.verifyEntry(); telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context); telemetry.startActivitySpan(this.leg); this.mapInputData(); //set state/status let transaction = this.store.transact(); await this.setState(transaction); await this.setStatus(0, transaction); //leg 1 never changes job status const txResponse = (await transaction.exec()); telemetry.mapActivityAttributes(); const jobStatus = this.resolveStatus(txResponse); //cycle the target ancestor transaction = this.store.transact(); const messageId = await this.cycleAncestorActivity(transaction); telemetry.setActivityAttributes({ 'app.activity.mid': messageId, 'app.job.jss': jobStatus, }); //exit early (`Cycle` activities only execute Leg 1) await collator_1.CollatorService.notarizeEarlyExit(this, transaction); (await transaction.exec()); return this.context.metadata.aid; } catch (error) { if (error instanceof errors_1.InactiveJobError) { this.logger.error('cycle-inactive-job-error', { error }); return; } else if (error instanceof errors_1.GenerationalError) { this.logger.info('process-event-generational-job-error', { error }); return; } else if (error instanceof errors_1.GetStateError) { this.logger.error('cycle-get-state-error', { error }); return; } else if (error instanceof errors_1.CollationError) { if (error.fault === 'duplicate') { this.logger.info('cycle-collation-overage', { job_id: this.context.metadata.jid, guid: this.context.metadata.guid, }); return; } //unknown collation error this.logger.error('cycle-collation-error', { error }); } else { this.logger.error('cycle-process-error', { error }); } telemetry?.setActivityError(error.message); throw error; } finally { telemetry?.endActivitySpan(); this.logger.debug('cycle-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid, }); } } /** * Trigger the target ancestor to execute in a cycle, * without violating the constraints of the DAG. Immutable * `individual activity state` will execute in a new dimensional * thread while `shared job state` can change. This * pattern allows for retries without violating the DAG. */ async cycleAncestorActivity(transaction) { //Cycle activity L1 is a standin for the target ancestor L1. //Input data mapping (mapInputData) allows for the //next dimensonal thread to execute with different //input data than the current dimensional thread this.mapInputData(); const streamData = { metadata: { guid: (0, utils_1.guid)(), jid: this.context.metadata.jid, gid: this.context.metadata.gid, dad: collator_1.CollatorService.resolveReentryDimension(this), aid: this.config.ancestor, spn: this.context['$self'].output.metadata?.l1s, trc: this.context.metadata.trc, }, data: this.context.data, }; return (await this.engine.router?.publishMessage(null, streamData, transaction)); } } exports.Cycle = Cycle;