TypeDrop

2026-05-07 Challenge

2026-05-07 Medium

Typed Job Queue Scheduler

You're building the background-job layer for a workflow automation platform. Raw job definitions arrive as `unknown` from a user-facing API; your scheduler must validate them, assign each job to a typed priority lane, execute lanes with a configurable concurrency limit, and return a strongly-typed execution report — with zero `any`.

Goals

  • Implement `validateJob` to safely narrow an `unknown` value into a typed `Job`, returning `null` for any schema violation.
  • Implement `buildQueues` to validate an array of unknowns and bucket valid jobs into a `PriorityQueues` Record by priority lane.
  • Implement `executeLane` to run jobs with a sliding-window concurrency limit, capturing both successes and failures without propagating rejections.
  • Implement `runScheduler` to orchestrate the full pipeline — validate, queue, execute lanes sequentially in priority order, and return a typed `SchedulerReport`.
challenge.ts

// Key types & main entry point — challenge.ts (preview)

export type Priority = "high" | "normal" | "low";

export interface Job {
  id: string;
  name: string;
  priority: Priority;
  durationMs: number;
  payload: Record<string, string | number | boolean>;
}

export type PriorityQueues = Record<Priority, Job[]>;

export type JobResult =
  | { status: "success"; jobId: string; jobName: string; durationMs: number }
  | { status: "failure"; jobId: string; jobName: string; reason: string };

export type JobRunner = (job: Job) => Promise<
  Extract<JobResult, { status: "success" }>
>;

// Your four tasks:
export function validateJob(raw: unknown): Job | null { /* TODO */ }
export function buildQueues(rawJobs: unknown[]): PriorityQueues { /* TODO */ }
export async function executeLane(
  jobs: Job[], runner: JobRunner, concurrency: number
): Promise<JobResult[]> { /* TODO */ }
export async function runScheduler(
  rawJobs: unknown[], runner: JobRunner, concurrency?: number
): Promise<SchedulerReport> { /* TODO */ }
Hints (click to reveal)

Hints

  • For `executeLane`, maintain an in-flight `Set` of Promises and use a drain loop — or process jobs in fixed-size chunks with `Promise.allSettled` — to respect the concurrency cap while preserving result order.
  • In `validateJob`, check `payload` values with `Object.entries` and verify each value's type with `typeof` — remember that `typeof null === 'object'`, so guard against that first.
  • Use the `status` discriminant on `JobResult` to narrow inside `runScheduler` when tallying `succeeded`, `failed`, and `totalSuccessfulDurationMs` — no type assertions needed.

Or clone locally

git clone -b challenge/2026-05-07 https://github.com/niltonheck/typedrop.git