From d54e91c6582ed160cf2f2fcf977e48b4439d133b Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Sun, 18 May 2025 22:54:15 -0700 Subject: snapshot --- hooks/server/job/activity.ts | 100 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 hooks/server/job/activity.ts (limited to 'hooks/server/job/activity.ts') diff --git a/hooks/server/job/activity.ts b/hooks/server/job/activity.ts new file mode 100644 index 0000000..14ea459 --- /dev/null +++ b/hooks/server/job/activity.ts @@ -0,0 +1,100 @@ +import { + Either, + ErrorSource, + type IActivity, + type IEither, + type ITraceable, + jsonModel, + JsonResponse, + LogLevel, + Metric, + PenguenoError, + type PenguenoRequest, + type ServerTrace, + TraceUtil, + validateExecutionEntries, +} from "@emprespresso/pengueno"; +import { isJob, type Job } from "@emprespresso/ci-model"; +import type { IJobQueuer } from "@emprespresso/ci-hooks"; + +const wellFormedJobMetric = Metric.fromName("Job.WellFormed"); + +const jobJsonTransformer = ( + j: ITraceable, +): IEither => + j.bimap(TraceUtil.withMetricTrace(wellFormedJobMetric)) + .map((tJson) => { + if (!isJob(tJson) || !validateExecutionEntries(tJson)) { + const err = "seems like a pwetty mawfomed job \\(-.-)/"; + tJson.trace.addTrace(LogLevel.WARN).trace(err); + return Either.left(new PenguenoError(err, 400)); + } + return Either.right(tJson); + }) + .peek((tJob) => + tJob.trace.trace( + tJob.get().fold((err) => + err ? wellFormedJobMetric.failure : wellFormedJobMetric.success + ), + ) + ) + .get(); + +export interface IJobHookActivity { + processHook: IActivity; +} + +const jobHookRequestMetric = Metric.fromName("JobHook.process"); +export class JobHookActivityImpl implements IJobHookActivity { + constructor( + private readonly queuer: IJobQueuer>, + ) {} + + private trace(r: ITraceable) { + return r.bimap(TraceUtil.withClassTrace(this)) + .bimap( + TraceUtil.withMetricTrace(jobHookRequestMetric), + ); + } + + public processHook(r: ITraceable) { + return this.trace(r).map(jsonModel(jobJsonTransformer)) + .map(async (tEitherJobJson) => { + const eitherJob = await tEitherJobJson.get(); + return eitherJob.flatMapAsync(async (job) => { + const eitherQueued = await tEitherJobJson.move(job) + .map(this.queuer.queue) + .get(); + return eitherQueued.mapLeft((e) => new PenguenoError(e.message, 500)); + }); + }) + .peek( + TraceUtil.promiseify((tJob) => + tJob.get().fold( + (err: PenguenoError | undefined, _val: string | undefined) => { + if (!err) { + tJob.trace.trace(jobHookRequestMetric.success); + tJob.trace.trace(`all queued up and weady to go :D !! ${_val}`); + return; + } + tJob.trace.trace( + err.source === ErrorSource.SYSTEM + ? jobHookRequestMetric.failure + : jobHookRequestMetric.warn, + ); + tJob.trace.addTrace(err.source).trace(`${err}`); + }, + ) + ), + ) + .map( + TraceUtil.promiseify((tEitherQueuedJob) => + new JsonResponse(r, tEitherQueuedJob.get(), { + status: tEitherQueuedJob.get() + .fold(({ status }, _val) => _val ? 200 : status), + }) + ), + ) + .get(); + } +} -- cgit v1.2.3-70-g09d2