The three base services —Documentation Index
Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-kit-redis-mongo-docker/llms.txt
Use this file to discover all available pages before exploring further.
MongooseService, RedisService, and LoggerService — form the infrastructure layer of the backtest-kit stack. They are registered in the IoC container and injected into every DB and cache service in the system. You rarely interact with them directly, but understanding their initialization contract, timeout behavior, and logging interface is essential when wiring up a new environment or debugging connectivity issues.
MongooseService
Wraps the Mongoose connection with a
singleshot init guard and a 15-second timeout. Emits lifecycle events and closes gracefully on SIGINT.RedisService
Wraps the ioredis client with the same
singleshot / 15-second timeout pattern, plus a 30-second keepalive ping loop defined in redis.ts.LoggerService
Ships a no-op logger by default. Call
setLogger() to plug in any object that satisfies the ILogger interface.MongooseService
MongooseService is the single authoritative owner of the Mongoose connection inside the IoC container. Its core responsibility is ensuring the connection is established exactly once — even when multiple services call waitForInit() concurrently.
waitForInit()
The method is wrapped with singleshot, which means the underlying async factory runs at most once and every subsequent caller receives the same cached promise. If the connection is already in readyState === 1 (connected) when the function is first called, it returns immediately.
If the connection has not been established, waitForInit races the waitForConnect promise against a 15-second sleep. When the timeout wins:
this.waitForInit.clear()resets the singleshot guard so the next caller can retry.- An
Error("Mongoose connection timeout")is thrown to the waiting caller.
Connection events
MongooseService registers listeners on the Mongoose connection for four lifecycle events:
| Event | Meaning |
|---|---|
connected | The TCP connection to MongoDB is open and authenticated. |
error | A connection-level error occurred; details are forwarded to loggerService. |
disconnected | The connection was lost; Mongoose will attempt to reconnect automatically. |
reconnected | The connection was successfully re-established after a drop. |
SIGINT handler
When the process receivesSIGINT (e.g., Ctrl+C in a terminal), MongooseService calls mongoose.connection.close() before allowing the process to exit. This ensures all pending write operations are flushed and the connection is torn down cleanly rather than being killed mid-operation.
IoC access
RedisService
RedisService follows the identical initialization contract as MongooseService, but targets the ioredis client. The singleshot guard, the 15-second race, and the timeout-clear-and-throw pattern are all the same.
waitForInit()
The guard checks redis.status === 'ready' before waiting. If the ioredis client is already in the ready state (e.g., the service was already initialized earlier in the process lifetime), it returns immediately without entering the race.
30-second keepalive ping
The underlyingredis.ts factory sets up a setInterval that sends a PING command every 30 seconds. This prevents cloud-hosted Redis instances (e.g., Redis on Render, Railway, or ElastiCache) from closing idle connections due to inactivity timeouts.
SIGINT handler
Theredis.ts factory registers a SIGINT listener that calls redis.disconnect(false) before the process exits. The false argument tells ioredis to close the connection immediately without waiting for in-flight commands to complete. This mirrors the graceful-close behaviour in MongooseService, but uses the ioredis-native disconnect method rather than a server-side close command.
IoC access
LoggerService
LoggerService is a thin wrapper that delegates to any object satisfying the ILogger interface. By default it uses NOOP_LOGGER — a no-op implementation that silently discards all messages. This means the library emits no console output unless you explicitly opt in.
The ILogger interface
topic string as their first argument. The topic is a short dot-separated or colon-separated identifier that describes the emitting service and operation (e.g., "MongooseService.waitForInit"). Remaining arguments are arbitrary values — objects, strings, errors — forwarded verbatim to the underlying logger.
LoggerService class
setLogger(logger: ILogger)
Call setLogger once during application bootstrap to replace the no-op with your own implementation. Any object that satisfies ILogger is valid — a console-based adapter, a Winston logger, a Pino instance wrapped in an adapter, or a custom structured logger.
setLogger is not thread-safe across async boundaries in the sense that any log calls already in-flight when you swap the logger will still go to the old instance. Always call setLogger before invoking waitForInfra() or any service that emits logs.IoC access
Initialization order
All three base services are initialized together by thewaitForInfra() helper in setup.ts, which calls mongoService.waitForInit() and redisService.waitForInit() in parallel before any DB or cache service is used. You do not need to call waitForInit() manually unless you are building a custom bootstrap sequence outside of the provided setup utilities.
Always call
waitForInfra() (or manually await both mongoService.waitForInit() and redisService.waitForInit()) before making any call to a DbService or CacheService. Both infrastructure connections must be established before the first adapter operation.globalThis binding
When lib/index.ts is first imported, it calls Object.assign(globalThis, { ioc }) after constructing the container. This means the ioc object is also available as a global variable in any module that runs in the same process — useful for REPL debugging or for modules that cannot easily import from backtest-kit directly.
Prefer the named
import { ioc } from "backtest-kit" in application code. The globalThis.ioc binding is a convenience for debugging and is not part of the public API contract.