From 7d4e4cd546db0b70b1daf98f7ee2457a5fd8aa17 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 21 Jun 2024 10:11:15 +1200 Subject: [PATCH 1/2] update cluster examples for latest /platform --- .../cluster-node/examples/sample-connect.ts | 27 ++++------ .../cluster-node/examples/sample-manager.ts | 38 ++++++------- .../cluster-node/examples/sample-shard.ts | 53 +++++++------------ 3 files changed, 46 insertions(+), 72 deletions(-) diff --git a/packages/cluster-node/examples/sample-connect.ts b/packages/cluster-node/examples/sample-connect.ts index 2566c4e197..02f0612b57 100644 --- a/packages/cluster-node/examples/sample-connect.ts +++ b/packages/cluster-node/examples/sample-connect.ts @@ -5,16 +5,11 @@ import * as StorageFile from "@effect/cluster-node/StorageFile" import * as Serialization from "@effect/cluster/Serialization" import * as Sharding from "@effect/cluster/Sharding" import * as ShardingConfig from "@effect/cluster/ShardingConfig" -import * as NodeClient from "@effect/platform-node/NodeHttpClient" -import { runMain } from "@effect/platform-node/NodeRuntime" -import * as HttpClient from "@effect/platform/HttpClient" +import { HttpClient, HttpClientRequest } from "@effect/platform" +import { NodeHttpClient, NodeRuntime } from "@effect/platform-node" import { Resolver } from "@effect/rpc" import { HttpResolver } from "@effect/rpc-http" -import * as Effect from "effect/Effect" -import * as Layer from "effect/Layer" -import * as Logger from "effect/Logger" -import * as LogLevel from "effect/LogLevel" -import * as Ref from "effect/Ref" +import { Effect, Layer, Logger, LogLevel, Ref } from "effect" import { CounterEntity, GetCurrent, Increment } from "./sample-common.js" const liveLayer = Effect.gen(function*(_) { @@ -37,9 +32,9 @@ const liveLayer = Effect.gen(function*(_) { Layer.provide(StorageFile.storageFile), Layer.provide(PodsRpc.podsRpc((podAddress) => HttpResolver.make( - HttpClient.client.fetchOk.pipe( - HttpClient.client.mapRequest( - HttpClient.request.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) + HttpClient.fetchOk.pipe( + HttpClient.mapRequest( + HttpClientRequest.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) ) ) ).pipe(Resolver.toClient) @@ -47,20 +42,20 @@ const liveLayer = Effect.gen(function*(_) { Layer.provide(ShardManagerClientRpc.shardManagerClientRpc( (shardManagerUri) => HttpResolver.make( - HttpClient.client.fetchOk.pipe( - HttpClient.client.mapRequest( - HttpClient.request.prependUrl(shardManagerUri) + HttpClient.fetchOk.pipe( + HttpClient.mapRequest( + HttpClientRequest.prependUrl(shardManagerUri) ) ) ).pipe(Resolver.toClient) )), Layer.provide(ShardingConfig.withDefaults({ shardingPort: 54322 })), Layer.provide(Serialization.json), - Layer.provide(NodeClient.layer) + Layer.provide(NodeHttpClient.layerUndici) ) Layer.launch(liveLayer).pipe( Logger.withMinimumLogLevel(LogLevel.All), Effect.tapErrorCause(Effect.logError), - runMain + NodeRuntime.runMain ) diff --git a/packages/cluster-node/examples/sample-manager.ts b/packages/cluster-node/examples/sample-manager.ts index ceadca3707..d349bd2aab 100644 --- a/packages/cluster-node/examples/sample-manager.ts +++ b/packages/cluster-node/examples/sample-manager.ts @@ -5,29 +5,22 @@ import * as StorageFile from "@effect/cluster-node/StorageFile" import * as ManagerConfig from "@effect/cluster/ManagerConfig" import * as PodsHealth from "@effect/cluster/PodsHealth" import * as ShardManager from "@effect/cluster/ShardManager" -import { NodeHttpServer } from "@effect/platform-node" -import { runMain } from "@effect/platform-node/NodeRuntime" -import * as HttpClient from "@effect/platform/HttpClient" -import * as HttpServer from "@effect/platform/HttpServer" +import { HttpClient, HttpClientRequest, HttpMiddleware, HttpRouter, HttpServer } from "@effect/platform" +import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Resolver } from "@effect/rpc" -import { HttpResolver, HttpRouter } from "@effect/rpc-http" -import { Context } from "effect" -import * as Effect from "effect/Effect" -import { pipe } from "effect/Function" -import * as Layer from "effect/Layer" -import * as Logger from "effect/Logger" -import * as LogLevel from "effect/LogLevel" +import { HttpResolver, HttpRouter as RpcHttpRouter } from "@effect/rpc-http" +import { Context, Effect, Layer, Logger, LogLevel } from "effect" import { createServer } from "node:http" const HttpLive = Layer.flatMap( Layer.effect(ManagerConfig.ManagerConfig, ManagerConfig.ManagerConfig), (config) => - HttpServer.router.empty.pipe( - HttpServer.router.post("/api/rest", HttpRouter.toHttpApp(ShardManagerServiceRpc.router)), - HttpServer.server.serve(HttpServer.middleware.logger), - HttpServer.server.withLogAddress, + HttpRouter.empty.pipe( + HttpRouter.post("/api/rest", RpcHttpRouter.toHttpApp(ShardManagerServiceRpc.router)), + HttpServer.serve(HttpMiddleware.logger), + HttpServer.withLogAddress, Layer.provide( - NodeHttpServer.server.layer(createServer, { + NodeHttpServer.layer(createServer, { port: Context.get(config, ManagerConfig.ManagerConfig).apiPort }) ), @@ -35,8 +28,7 @@ const HttpLive = Layer.flatMap( ) ) -const liveShardingManager = pipe( - Effect.never, +const liveShardingManager = Effect.never.pipe( Layer.scopedDiscard, Layer.provide(HttpLive), Layer.provide(ShardManager.live), @@ -44,19 +36,19 @@ const liveShardingManager = pipe( Layer.provide(PodsHealth.local), Layer.provide(PodsRpc.podsRpc((podAddress) => HttpResolver.make( - HttpClient.client.fetchOk.pipe( - HttpClient.client.mapRequest( - HttpClient.request.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) + HttpClient.fetchOk.pipe( + HttpClient.mapRequest( + HttpClientRequest.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) ) ) ).pipe(Resolver.toClient) )), Layer.provide(ManagerConfig.fromConfig), - Layer.provide(HttpClient.client.layer) + Layer.provide(HttpClient.layer) ) Layer.launch(liveShardingManager).pipe( Logger.withMinimumLogLevel(LogLevel.All), Effect.tapErrorCause(Effect.logError), - runMain + NodeRuntime.runMain ) diff --git a/packages/cluster-node/examples/sample-shard.ts b/packages/cluster-node/examples/sample-shard.ts index 3514107d35..0b73fa6d0a 100644 --- a/packages/cluster-node/examples/sample-shard.ts +++ b/packages/cluster-node/examples/sample-shard.ts @@ -7,33 +7,23 @@ import * as RecipientBehaviour from "@effect/cluster/RecipientBehaviour" import * as Serialization from "@effect/cluster/Serialization" import * as Sharding from "@effect/cluster/Sharding" import * as ShardingConfig from "@effect/cluster/ShardingConfig" -import { NodeHttpServer } from "@effect/platform-node" -import * as NodeClient from "@effect/platform-node/NodeHttpClient" -import { runMain } from "@effect/platform-node/NodeRuntime" -import * as HttpClient from "@effect/platform/HttpClient" -import * as HttpServer from "@effect/platform/HttpServer" +import { HttpClient, HttpClientRequest, HttpMiddleware, HttpRouter, HttpServer } from "@effect/platform" +import { NodeHttpClient, NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Resolver } from "@effect/rpc" -import { HttpResolver, HttpRouter } from "@effect/rpc-http" -import * as Context from "effect/Context" -import * as Effect from "effect/Effect" -import * as Exit from "effect/Exit" -import { pipe } from "effect/Function" -import * as Layer from "effect/Layer" -import * as Logger from "effect/Logger" -import * as LogLevel from "effect/LogLevel" -import * as Ref from "effect/Ref" +import { HttpResolver, HttpRouter as RpcHttpRouter } from "@effect/rpc-http" +import { Context, Effect, Exit, Layer, Logger, LogLevel, Ref } from "effect" import { createServer } from "node:http" import { CounterEntity } from "./sample-common.js" const HttpLive = Layer.flatMap( Layer.effect(ShardingConfig.ShardingConfig, ShardingConfig.ShardingConfig), (config) => - HttpServer.router.empty.pipe( - HttpServer.router.post("/api/rest", HttpRouter.toHttpApp(ShardingServiceRpc.router)), - HttpServer.server.serve(HttpServer.middleware.logger), - HttpServer.server.withLogAddress, + HttpRouter.empty.pipe( + HttpRouter.post("/api/rest", RpcHttpRouter.toHttpApp(ShardingServiceRpc.router)), + HttpServer.serve(HttpMiddleware.logger), + HttpServer.withLogAddress, Layer.provide( - NodeHttpServer.server.layer(createServer, { + NodeHttpServer.layer(createServer, { port: Context.get(config, ShardingConfig.ShardingConfig).shardingPort }) ), @@ -49,20 +39,17 @@ const liveLayer = Sharding.registerEntity( (entityId, message, stateRef) => { switch (message._tag) { case "Increment": - return pipe( - Ref.update(stateRef, (count) => count + 1), + return Ref.update(stateRef, (count) => count + 1).pipe( Effect.zipLeft(Effect.logInfo(`Counter ${entityId} incremented`)), Effect.as(MessageState.Processed(Exit.void)) ) case "Decrement": - return pipe( - Ref.update(stateRef, (count) => count - 1), + return Ref.update(stateRef, (count) => count - 1).pipe( Effect.zipLeft(Effect.logInfo(`Counter ${entityId} decremented`)), Effect.as(MessageState.Processed(Exit.void)) ) case "GetCurrent": - return pipe( - Ref.get(stateRef), + return Ref.get(stateRef).pipe( Effect.exit, Effect.map((result) => MessageState.Processed(result)) ) @@ -77,9 +64,9 @@ const liveLayer = Sharding.registerEntity( Layer.provide(StorageFile.storageFile), Layer.provide(PodsRpc.podsRpc((podAddress) => HttpResolver.make( - HttpClient.client.fetchOk.pipe( - HttpClient.client.mapRequest( - HttpClient.request.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) + HttpClient.fetchOk.pipe( + HttpClient.mapRequest( + HttpClientRequest.prependUrl(`http://${podAddress.host}:${podAddress.port}/api/rest`) ) ) ).pipe(Resolver.toClient) @@ -87,20 +74,20 @@ const liveLayer = Sharding.registerEntity( Layer.provide(ShardManagerClientRpc.shardManagerClientRpc( (shardManagerUri) => HttpResolver.make( - HttpClient.client.fetchOk.pipe( - HttpClient.client.mapRequest( - HttpClient.request.prependUrl(shardManagerUri) + HttpClient.fetchOk.pipe( + HttpClient.mapRequest( + HttpClientRequest.prependUrl(shardManagerUri) ) ) ).pipe(Resolver.toClient) )), Layer.provide(Serialization.json), - Layer.provide(NodeClient.layer), + Layer.provide(NodeHttpClient.layerUndici), Layer.provide(ShardingConfig.fromConfig) ) Layer.launch(liveLayer).pipe( Logger.withMinimumLogLevel(LogLevel.Debug), Effect.tapErrorCause(Effect.logError), - runMain + NodeRuntime.runMain ) From e7c9e89734c52e3f5cffa0867a913260a23f1ab0 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 21 Jun 2024 10:22:22 +1200 Subject: [PATCH 2/2] ignore sql container errors in tests --- packages/sql-drizzle/test/Mysql.test.ts | 10 ++++++++-- packages/sql-drizzle/test/Pg.test.ts | 14 ++++++++++++-- packages/sql-drizzle/test/utils.ts | 20 +++++++++++++++----- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/sql-drizzle/test/Mysql.test.ts b/packages/sql-drizzle/test/Mysql.test.ts index ef93564fdc..57f7888932 100644 --- a/packages/sql-drizzle/test/Mysql.test.ts +++ b/packages/sql-drizzle/test/Mysql.test.ts @@ -21,7 +21,10 @@ describe.sequential("Mysql", () => { yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" }) const results = yield* db.select().from(users) assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "alice" }]) - }).pipe(Effect.provide(MysqlContainer.DrizzleLive)), { timeout: 60000 }) + }).pipe( + Effect.provide(MysqlContainer.DrizzleLive), + Effect.catchTag("ContainerError", () => Effect.void) + ), { timeout: 60000 }) it.effect("remote callback", () => Effect.gen(function*(_) { @@ -31,5 +34,8 @@ describe.sequential("Mysql", () => { yield* Effect.promise(() => db.insert(users).values({ name: "Alice", snakeCase: "snake" })) const results = yield* Effect.promise(() => db.select().from(users)) assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "snake" }]) - }).pipe(Effect.provide(MysqlContainer.DrizzleLive)), { timeout: 60000 }) + }).pipe( + Effect.provide(MysqlContainer.DrizzleLive), + Effect.catchTag("ContainerError", () => Effect.void) + ), { timeout: 60000 }) }) diff --git a/packages/sql-drizzle/test/Pg.test.ts b/packages/sql-drizzle/test/Pg.test.ts index 4db1a84708..8d2c04437e 100644 --- a/packages/sql-drizzle/test/Pg.test.ts +++ b/packages/sql-drizzle/test/Pg.test.ts @@ -21,7 +21,12 @@ describe.sequential("Pg", () => { yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" }) const results = yield* db.select().from(users) assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "alice" }]) - }).pipe(Effect.provide(PgContainer.DrizzleLive)), { timeout: 60000 }) + }).pipe( + Effect.provide(PgContainer.DrizzleLive), + Effect.catchTag("ContainerError", () => Effect.void) + ), { + timeout: 60000 + }) it.effect("remote callback", () => Effect.gen(function*(_) { @@ -31,5 +36,10 @@ describe.sequential("Pg", () => { yield* Effect.promise(() => db.insert(users).values({ name: "Alice", snakeCase: "snake" })) const results = yield* Effect.promise(() => db.select().from(users)) assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "snake" }]) - }).pipe(Effect.provide(PgContainer.DrizzleLive)), { timeout: 60000 }) + }).pipe( + Effect.provide(PgContainer.DrizzleLive), + Effect.catchTag("ContainerError", () => Effect.void) + ), { + timeout: 60000 + }) }) diff --git a/packages/sql-drizzle/test/utils.ts b/packages/sql-drizzle/test/utils.ts index d2cecc2de9..03f5e1c33d 100644 --- a/packages/sql-drizzle/test/utils.ts +++ b/packages/sql-drizzle/test/utils.ts @@ -5,7 +5,11 @@ import * as Pg from "@effect/sql-pg" import type { StartedMySqlContainer } from "@testcontainers/mysql" import { MySqlContainer } from "@testcontainers/mysql" import { PostgreSqlContainer, type StartedPostgreSqlContainer } from "@testcontainers/postgresql" -import { Config, Context, Effect, Layer, Secret } from "effect" +import { Config, Context, Data, Effect, Layer, Redacted } from "effect" + +export class ContainerError extends Data.TaggedError("ContainerError")<{ + cause: unknown +}> {} export class PgContainer extends Context.Tag("test/PgContainer")< PgContainer, @@ -14,7 +18,10 @@ export class PgContainer extends Context.Tag("test/PgContainer")< static Live = Layer.scoped( this, Effect.acquireRelease( - Effect.promise(() => new PostgreSqlContainer("postgres:alpine").start()), + Effect.tryPromise({ + try: () => new PostgreSqlContainer("postgres:alpine").start(), + catch: (cause) => new ContainerError({ cause }) + }), (container) => Effect.promise(() => container.stop()) ) ) @@ -23,7 +30,7 @@ export class PgContainer extends Context.Tag("test/PgContainer")< Effect.gen(function*(_) { const container = yield* _(PgContainer) return Pg.client.layer({ - url: Config.succeed(Secret.fromString(container.getConnectionUri())) + url: Config.succeed(Redacted.make(container.getConnectionUri())) }) }) ).pipe(Layer.provide(this.Live)) @@ -38,7 +45,10 @@ export class MysqlContainer extends Context.Tag("test/MysqlContainer")< static Live = Layer.scoped( this, Effect.acquireRelease( - Effect.promise(() => new MySqlContainer("mysql:lts").start()), + Effect.tryPromise({ + try: () => new MySqlContainer("mysql:lts").start(), + catch: (cause) => new ContainerError({ cause }) + }), (container) => Effect.promise(() => container.stop()) ) ) @@ -47,7 +57,7 @@ export class MysqlContainer extends Context.Tag("test/MysqlContainer")< Effect.gen(function*(_) { const container = yield* _(MysqlContainer) return Mysql.client.layer({ - url: Config.succeed(Secret.fromString(container.getConnectionUri())) + url: Config.succeed(Redacted.make(container.getConnectionUri())) }) }) ).pipe(Layer.provide(this.Live))