Skip to content

Instantly share code, notes, and snippets.

@swyxio
Last active February 15, 2022 17:55
Show Gist options
  • Save swyxio/4524d2f9629792fe8b056e320b6c6118 to your computer and use it in GitHub Desktop.
Save swyxio/4524d2f9629792fe8b056e320b6c6118 to your computer and use it in GitHub Desktop.
sample Temporal workflow - see https://youtu.be/2pxZgGhT-Xo for context and full video!
import * as wf from '@temporalio/workflow';
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds';
import type * as activities from './activities';
import { sub } from 'date-fns'
const {
doMaintenance,
notifySubscribers
} = wf.proxyActivities<typeof activities>({
// remember to adjust timeouts!
});
export const startMaintenanceSignal = wf.defineSignal('startMaintenance');
export const completeMaintenanceSignal = wf.defineSignal('completeMaintenance');
export const MaintenanceStatusQuery = wf.defineQuery<boolean>('MaintenanceStatus');
// start a "maintenance" at a specified future date
export async function MaintenanceWF({
startDateTime,
duration,
notifySubscribersNow,
automationOptions
}: inputArgs) {
let isMaintenanceComplete = false;
wf.setHandler(MaintenanceStatusQuery, () => isMaintenanceComplete);
if (notifySubscribersNow) await notifySubscribers('maintenance scheduled')
if (automationOptions.notifyBefore) {
await sleepUntil(sub(startDateTime, {
minutes: automationOptions.notifyBefore // integer
}));
} else {
await sleepUntil(startDateTime);
}
// starting and doing maintenance
if (automationOptions.start.type === "automatic") {
if (automationOptions.start.notifySubscribers) await notifySubscribers('starting maintenance');
await doMaintenance(duration);
} else {
let isWaiting = true;
wf.setHandler(startMaintenanceSignal, () => void (isWaiting = false));
await wf.condition(() => !isWaiting);
await doMaintenance(duration);
}
// completing maintenance
if (automationOptions.complete.type === "automatic") {
if (automationOptions.complete.notifySubscribers) await notifySubscribers('completed maintenance');
isMaintenanceComplete = true;
return; // end the wf, we are done
} else {
let isWaiting = true;
wf.setHandler(completeMaintenanceSignal, () => void (isWaiting = false));
await wf.condition(() => !isWaiting);
isMaintenanceComplete = true;
return; // end the wf, we are done
}
}
//... misc details
// https://docs.temporal.io/docs/typescript/workflows/#sleep
async function sleepUntil(futureDate, fromDate = new Date()) {
const timeUntilDate = differenceInMilliseconds(
new Date(futureDate),
fromDate
);
return wf.sleep(timeUntilDate);
}
type inputArgs = {
//...
}
import { Connection, WorkflowClient } from '@temporalio/client';
// signalName is either 'startMaintenanceSignal' or 'completeMaintenanceSignal'
async function run(customerId, signalName) {
const client = new WorkflowClient();
const handle = await client.getHandle('wf-id-' + customerId);
await handle.signal(signalName);
}
run().catch((err) => {
console.error(err);
process.exit(1);
});
import { Connection, WorkflowClient } from '@temporalio/client';
import { MaintenanceWF } from './workflows';
async function run({
startDateTime,
duration,
notifySubscribersNow,
customerId
}) {
const client = new WorkflowClient();
const handle = await client.start(MaintenanceWF, {
args: [{
startDateTime,
duration,
notifySubscribersNow
}],
taskQueue: 'instatus',
workflowId: 'wf-id-' + customerId,
});
console.log(`Started workflow ${handle.workflowId}`);
}
run().catch((err) => {
console.error(err);
process.exit(1);
});
import { Worker } from '@temporalio/worker';
import * as activities from './activities';
async function run() {
const worker = await Worker.create({
workflowsPath: require.resolve('./workflows'),
activities,
taskQueue: 'instatus',
});
await worker.run();
}
run().catch((err) => {
console.error(err);
process.exit(1);
});
@swyxio
Copy link
Author

swyxio commented Feb 15, 2022

sample Temporal workflow - see https://youtu.be/2pxZgGhT-Xo for context and full video!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment