Skip to content

Instantly share code, notes, and snippets.

@igalshilman
Created November 17, 2025 18:21
Show Gist options
  • Select an option

  • Save igalshilman/277de79c1d93727bb5cab1d2b186a870 to your computer and use it in GitHub Desktop.

Select an option

Save igalshilman/277de79c1d93727bb5cab1d2b186a870 to your computer and use it in GitHub Desktop.
import {
service,
serve,
type Context,
RestatePromise,
TerminalError,
} from "@restatedev/restate-sdk";
async function* randomGreeting() {
const greetings = [
"Hello",
"Hi",
"Greetings",
"Salutations",
"Howdy",
"Hey there",
"Good to see you",
"Welcome",
"Ahoy",
"Yo",
];
for (const greeting of greetings) {
yield greeting;
}
}
type TaskGeneratorResult<T> =
| {
type: "done";
value?: undefined;
}
| { type: "next"; value: T }
| { type: "error"; value?: undefined };
class TaskGenerator<T> {
private generator: AsyncGenerator<T> | undefined = undefined;
constructor(
private readonly context: Context,
private readonly fn: () => AsyncGenerator<T>
) {}
next(): RestatePromise<TaskGeneratorResult<T>> {
return this.context.run("next", async () => {
if (this.generator === undefined) {
this.generator = this.fn();
}
try {
const { value, done } = await this.generator.next();
if (done) {
return { type: "done" } as const;
} else {
return { type: "next", value } as const;
}
} catch (error) {
return { type: "error" } as const;
}
});
}
}
const greeter = service({
name: "greeter",
handlers: {
greet: async (ctx: Context, name: string) => {
const generator = new TaskGenerator(ctx, randomGreeting);
while (true) {
const result = await generator.next();
if (result.type === "done") {
break;
} else if (result.type === "next") {
const greeting = result.value;
ctx.console.log(`${greeting}, ${name}!`);
} else if (result.type === "error") {
throw new TerminalError("Error generating greeting");
}
}
},
},
});
export type Greeter = typeof greeter;
serve({ services: [greeter] });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment