Merge commit '36c66dd290d3ce6eb1ccd310d0c658d4a32bb8eb' as 'repos/effect'
This commit is contained in:
84
repos/effect/packages/platform-node/test/NodeRedis.test.ts
Normal file
84
repos/effect/packages/platform-node/test/NodeRedis.test.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { NodeRedis } from "@effect/platform-node"
|
||||
import { assert, it } from "@effect/vitest"
|
||||
import { RedisContainer } from "@testcontainers/redis"
|
||||
import { Effect, Layer, Schema } from "effect"
|
||||
import * as PersistedCacheTest from "effect-test/unstable/persistence/PersistedCacheTest"
|
||||
import * as PersistedQueueTest from "effect-test/unstable/persistence/PersistedQueueTest"
|
||||
import { PersistedQueue, Persistence } from "effect/unstable/persistence"
|
||||
|
||||
const RedisLayer = Layer.unwrap(
|
||||
Effect.gen(function*() {
|
||||
const container = yield* Effect.acquireRelease(
|
||||
Effect.promise(() => new RedisContainer("redis:alpine").start()),
|
||||
(container) => Effect.promise(() => container.stop())
|
||||
)
|
||||
return NodeRedis.layer({
|
||||
host: container.getHost(),
|
||||
port: container.getMappedPort(6379)
|
||||
})
|
||||
}).pipe(
|
||||
Effect.catchCause(() => Effect.fail(new PersistedCacheTest.TransientError()))
|
||||
)
|
||||
)
|
||||
|
||||
PersistedCacheTest.suite(
|
||||
"NodeRedis",
|
||||
Persistence.layerRedis.pipe(Layer.provide(RedisLayer))
|
||||
)
|
||||
|
||||
PersistedQueueTest.suite(
|
||||
"NodeRedis",
|
||||
// short intervals so the periodic reset runs while the suite's takes are
|
||||
// in flight
|
||||
PersistedQueue.layerStoreRedis({
|
||||
pollInterval: "50 millis",
|
||||
lockRefreshInterval: "100 millis"
|
||||
}).pipe(Layer.provide(RedisLayer))
|
||||
)
|
||||
|
||||
const PersistedQueueRedisLayer = Layer.mergeAll(
|
||||
RedisLayer,
|
||||
PersistedQueue.layer.pipe(
|
||||
Layer.provideMerge(
|
||||
PersistedQueue.layerStoreRedis().pipe(Layer.provide(RedisLayer))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
it.layer(PersistedQueueRedisLayer, { timeout: "30 seconds" })(
|
||||
"PersistedQueue (NodeRedis)",
|
||||
(it) => {
|
||||
// The shared PersistedQueue suite can only assert that exhausted elements
|
||||
// are no longer delivered, which is also true if they are silently
|
||||
// dropped. There is no public API for reading failed elements, so
|
||||
// verifying they are preserved in the dead-letter list requires
|
||||
// inspecting Redis directly.
|
||||
it.effect("moves exhausted elements to the failed list", () =>
|
||||
Effect.gen(function*() {
|
||||
const redis = yield* NodeRedis.NodeRedis
|
||||
const queueName = "test-redis-failed"
|
||||
|
||||
const queue = yield* PersistedQueue.make({
|
||||
name: queueName,
|
||||
schema: RedisItem
|
||||
})
|
||||
const id = yield* queue.offer({ n: 42 })
|
||||
const error = yield* queue.take(() => Effect.fail("boom"), { maxAttempts: 1 }).pipe(Effect.flip)
|
||||
assert.strictEqual(error, "boom")
|
||||
|
||||
const failed = yield* redis.use((client) => client.lrange(`effectq:${queueName}:failed`, 0, -1))
|
||||
assert.strictEqual(failed.length, 1)
|
||||
const failedItem = JSON.parse(failed[0])
|
||||
assert.strictEqual(failedItem.id, id)
|
||||
assert.deepStrictEqual(failedItem.element, { n: 42 })
|
||||
assert.strictEqual(failedItem.attempts, 1)
|
||||
|
||||
const pending = yield* redis.use((client) => client.hlen(`effectq:${queueName}:pending`))
|
||||
assert.strictEqual(pending, 0)
|
||||
}))
|
||||
}
|
||||
)
|
||||
|
||||
const RedisItem = Schema.Struct({
|
||||
n: Schema.Number
|
||||
})
|
||||
Reference in New Issue
Block a user