local.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435
  1. import { Effect, Layer } from "effect"
  2. import { LocationServiceMap } from "../../location-layer"
  3. import { SessionRunCoordinator } from "../run-coordinator"
  4. import { SessionSchema } from "../schema"
  5. import { SessionStore } from "../store"
  6. import { SessionExecution } from "../execution"
  7. /** Current-process routing for implicit-local Locations. Future remote placement belongs here. */
  8. export const layer = Layer.effect(
  9. SessionExecution.Service,
  10. Effect.gen(function* () {
  11. const store = yield* SessionStore.Service
  12. const locations = yield* LocationServiceMap
  13. const scope = yield* Effect.scope
  14. const withCoordinator = Effect.fnUntraced(function* <A, E>(
  15. sessionID: SessionSchema.ID,
  16. use: (coordinator: SessionRunCoordinator.Interface) => Effect.Effect<A, E>,
  17. ) {
  18. const session = yield* store.get(sessionID)
  19. if (!session) return yield* Effect.die(`Session not found: ${sessionID}`)
  20. return yield* SessionRunCoordinator.Service.use(use).pipe(Effect.provide(locations.get(session.location)))
  21. })
  22. return SessionExecution.Service.of({
  23. resume: Effect.fn("SessionExecution.resume")(function* (sessionID) {
  24. return yield* withCoordinator(sessionID, (coordinator) => coordinator.run(sessionID))
  25. }),
  26. wake: Effect.fn("SessionExecution.wake")(function* (sessionID) {
  27. yield* withCoordinator(sessionID, (coordinator) =>
  28. coordinator.wake(sessionID).pipe(Effect.andThen(coordinator.awaitIdle(sessionID))),
  29. ).pipe(Effect.forkIn(scope), Effect.asVoid)
  30. }),
  31. })
  32. }),
  33. )