Job
Source:
src/Kubernetes/Job.ts
Run-to-completion Kubernetes compute on any cluster — the Kubernetes
analog of AWS.ECS.Task.
Job provisions a Kubernetes Job (or CronJob when schedule is
set) via server-side apply and a ServiceAccount, plus — through the
target cluster’s platform adapter — workload identity and a container
image from exactly one of three sources flat on props: main (bundle an
inline Effect program whose impl returns { run }), context (build
your own Dockerfile), or image (a pre-built registry reference). On
AWS.EKS.Cluster targets, bindings attach env vars to the pod and IAM
policy statements to a generated pod-identity role, exactly like
Kubernetes.Deployment.
Creating a Job
Section titled “Creating a Job”Remote image (external — no Effect runtime in the container)
const migrate = yield* Kubernetes.Job("DbMigrate", { cluster, image: "ghcr.io/acme/migrator:v3", backoffLimit: 2,});Inline Effect program with a DynamoDB binding (EKS)
const seed = yield* Kubernetes.Job( "SeedData", { cluster, main: import.meta.url }, Effect.gen(function* () { const putItem = yield* AWS.DynamoDB.PutItem(table); return { run: Effect.gen(function* () { yield* putItem({ Item: { id: { S: "seed" } } }); }), }; }).pipe(Effect.provide(AWS.DynamoDB.PutItemHttp)),);Tagged Effect program
export class Backfill extends Kubernetes.Job<Backfill, { progress: () => Effect.Effect<number>;}>()("Backfill") {}
export default Backfill.make( { cluster, main: import.meta.url, backoffLimit: 1 }, Effect.gen(function* () { return { run: Effect.gen(function* () { }), progress: () => Effect.succeed(0), }; }),);Bundling & Tree-shaking
Section titled “Bundling & Tree-shaking”main is bundled with rolldown at deploy time. Top-level calls in the
effect, @effect/*, alchemy, @alchemy.run/*, and
@distilled.cloud/* packages receive #__PURE__ annotations by
default, so anything the job doesn’t use from those packages is
tree-shaken out of the bundle. Any other package — including your own
app — is left untouched unless you list it explicitly.
Treat additional packages as pure
Pass package names (or picomatch globs) via build.pure.packages to
annotate them in addition to the defaults.
{ main: import.meta.url, build: { pure: { packages: ["my-lib", "@my-scope/*"] }, },}Listing a package annotates calls whose result is bound (variable
initializers, exports) — safe anywhere. If a listed package also
declares "sideEffects": false (or []) in its package.json, that
combination opts it into full annotation: top-level calls whose result
is discarded (e.g. router.on("/path", handler) registrations) are
also marked pure and deleted under minification when unused. Only list
a sideEffects: false package if its modules really are free of
meaningful top-level side effects. The effect, alchemy, and
@distilled.cloud defaults declare exactly that, on purpose — their
modules are designed to be fully tree-shakeable.
Disable pure annotations
{ main: import.meta.url, build: { pure: false },}Scheduling
Section titled “Scheduling”const nightly = yield* Kubernetes.Job("NightlyBackfill", { cluster, main: import.meta.url, schedule: "0 3 * * *",});