Skip to content

Commit 8cca763

Browse files
authored
Effect-native otel integration (#425)
1 parent 174759e commit 8cca763

54 files changed

Lines changed: 1815 additions & 1319 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/changesets.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
timeout-minutes: 10
1515
steps:
1616
- uses: actions/checkout@v6
17-
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init --depth 1 konfik"
17+
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init konfik"
1818
- uses: ./konfik/.github/actions/configure_environment
1919
- run: pnpm run build
2020
- uses: changesets/action@v1

.github/workflows/checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
contents: read
1818
steps:
1919
- uses: actions/checkout@v6
20-
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init --depth 1 konfik"
20+
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init konfik"
2121
- uses: ./konfik/.github/actions/configure_environment
2222
- run: pnpm build
2323
# - run: pnpm test

.github/workflows/deploy-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
environment: docs
1818
steps:
1919
- uses: actions/checkout@v6
20-
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init --depth 1 konfik"
20+
- run: "git -c url.https://github.com/.insteadOf=git@github.com: submodule update --init konfik"
2121
- uses: ./konfik/.github/actions/configure_environment
2222
- run: pnpm build
2323
- run: pnpm build
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# HTTP Upgrades
2+
3+
`Namespace.upgrade(name, attachments)` is the handoff from HTTP to the Durable Object.
4+
5+
An HTTP route decides:
6+
7+
- which actor name to connect to
8+
- which actor type to use
9+
- what the initial attachments should be
10+
11+
`upgrade(...)` handles the rest.
12+
13+
## Upgrade from a route
14+
15+
```ts
16+
import { Effect, Layer } from "effect"
17+
import { HttpRouter } from "effect/unstable/http"
18+
19+
import { ChatNamespace } from "./chat/ChatNamespace.ts"
20+
import { LobbyNamespace } from "./lobby/LobbyNamespace.ts"
21+
22+
export const ApiLive = Layer.mergeAll(
23+
HttpRouter.add(
24+
"GET",
25+
"/connect",
26+
Effect.gen(function* () {
27+
const sessionToken = yield* readSessionToken
28+
const user = yield* lookupUser(sessionToken)
29+
30+
if (user) {
31+
const roomId = yield* getActiveRoom(user.id)
32+
return yield* ChatNamespace.upgrade(roomId, { userId: user.id })
33+
}
34+
35+
return yield* LobbyNamespace.upgrade(sessionToken, {})
36+
}),
37+
),
38+
)
39+
```
40+
41+
Every request that upgrades with the same actor name lands in the same Durable Object instance.
42+
43+
## What upgrade does
44+
45+
On the Cloudflare side, `upgrade(...)`:
46+
47+
- resolves the Durable Object by actor name
48+
- validates that the connecting WebSocket is using the expected Liminal client id
49+
- serializes attachments onto the WebSocket
50+
- returns the `101 Switching Protocols` response
51+
52+
The validation step is why client and actor definitions must line up. If the wrong client tries to connect, the session
53+
fails with an audition error rather than silently misbehaving.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Worker Entrypoint
2+
3+
The Worker entrypoint usually exports:
4+
5+
- a default `fetch` handler
6+
- each Durable Object class as a named export
7+
8+
`Worker.make(...)` supplies the Worker-side runtime for ordinary HTTP handling. `WorkerdActorNamespace` separately
9+
manages the Durable Object runtime for actor messages.
10+
11+
## Build the entrypoint
12+
13+
```ts
14+
// main.ts
15+
import { Effect, Layer } from "effect"
16+
import { Assets, Worker } from "effect-workerd"
17+
import { HttpRouter, HttpServerResponse } from "effect/unstable/http"
18+
19+
import * as GameState from "./Games.ts"
20+
import { KvLive } from "./KvLive.ts"
21+
import { TicTacToeNamespace } from "./TicTacToeNamespace.ts"
22+
23+
export { TicTacToeNamespace }
24+
25+
const ApiLive = Layer.mergeAll(
26+
HttpRouter.add("GET", "/", Effect.succeed(HttpServerResponse.text("ok"))),
27+
HttpRouter.add(
28+
"GET",
29+
"/play",
30+
Effect.gen(function* () {
31+
const { gameId, player } = yield* GameState.init
32+
return yield* TicTacToeNamespace.upgrade(gameId, { player })
33+
}),
34+
),
35+
HttpRouter.cors({
36+
allowedHeaders: ["*"],
37+
allowedMethods: ["*"],
38+
allowedOrigins: ["*"],
39+
}),
40+
HttpRouter.add("*", "/*", Assets.forward),
41+
)
42+
43+
export default Worker.make({
44+
handler: ApiLive.pipe(HttpRouter.toHttpEffect, Effect.flatten),
45+
prelude: Layer.mergeAll(KvLive, TicTacToeNamespace.layer("TICTACTOE"), Assets.layer("ASSETS")),
46+
})
47+
```
48+
49+
## Things to notice
50+
51+
- `HttpRouter.add(method, path, effect)` mounts a single route.
52+
- `HttpRouter.cors(...)` wires up CORS for every route in the router.
53+
- `HttpRouter.add("*", "/*", Assets.forward)` falls through to the Cloudflare Assets binding for unmatched requests.
54+
- `Worker.make({ handler, prelude })` produces the Worker `fetch` export.
55+
- The Durable Object class must be re-exported from the Worker entrypoint.

docs/pages/actors-handlers-and-lifecycle.mdx

Lines changed: 0 additions & 202 deletions
This file was deleted.

0 commit comments

Comments
 (0)