DI Integration
The semaphoreFactoryResolverDiFactory function creates an ISemaphoreFactoryResolver whose underlying resolver is resolved from a DI container.
The returned proxy implements both ISemaphoreFactoryResolver and ISemaphoreFactory:
use(adapterName?)selects an adapter on the resolvedSemaphoreFactoryResolver.create(key, settings)creates a semaphore through the resolver's default adapter.
The proxy is wired to the container during container.init(). Create it before calling init(); calling use() or create() before the container is initialized throws an error.
Initial configuration
Set up the memory and Redis semaphore adapters, create the container, then register the SemaphoreFactoryResolver and wrap it with semaphoreFactoryResolverDiFactory:
1. Set up the memory semaphore adapter
./samples/memory-semaphore-adapter.ts
import { MemorySemaphoreAdapter } from "eridu-tech/semaphore/memory-semaphore-adapter";
export const memorySemaphoreAdapter = new MemorySemaphoreAdapter();
2. Set up the Redis semaphore adapter
./samples/redis-semaphore-adapter.ts
import { RedisSemaphoreAdapter } from "eridu-tech/semaphore/redis-semaphore-adapter";
import { Redis } from "ioredis";
export const redisSemaphoreAdapter = new RedisSemaphoreAdapter(
new Redis("YOUR_REDIS_CONNECTION_STRING"),
);
3. Create the dependency injection container
./samples/container.ts
import { Container } from "eridu-tech/di";
import { ExecutionContext } from "eridu-tech/execution-context";
import { AlsExecutionContextAdapter } from "eridu-tech/execution-context/als-execution-context-adapter";
export const executionContext = new ExecutionContext(
new AlsExecutionContextAdapter(),
);
export const container = new Container({ executionContext });
4. Register and initialize the semaphore factory resolver
./samples/semaphore-factory-resolver-di-factory.ts
import { SemaphoreFactoryResolver } from "eridu-tech/semaphore";
import { ProxySemaphoreFactoryResolver } from "eridu-tech/semaphore/di";
import { container } from "./container.js";
import { memorySemaphoreAdapter } from "./memory-semaphore-adapter.js";
import { redisSemaphoreAdapter } from "./redis-semaphore-adapter.js";
type Adapters = "memory" | "redis";
const semaphoreFactoryResolver = new SemaphoreFactoryResolver<Adapters>({
adapters: {
memory: memorySemaphoreAdapter,
redis: redisSemaphoreAdapter,
},
defaultAdapter: "memory",
});
await semaphoreFactoryResolver.init();
container.registerValue({
token: SemaphoreFactoryResolver,
value: semaphoreFactoryResolver,
});
// Create the proxy before container.init()
export const semaphoreFactory = new ProxySemaphoreFactoryResolver<Adapters>({
container,
resolverToken: SemaphoreFactoryResolver,
});
await container.init();
Usage
1. Using the default adapter
./samples/semaphore-factory-resolver-di-factory-default-adapter.ts
import { semaphoreFactory } from "./semaphore-factory-resolver-di-factory.js";
// Uses the adapter configured as the default (memory)
await semaphoreFactory
.create("shared-resource", {
limit: 2,
})
.runOrFail(async () => {
// code to run
});
2. Specifying an adapter explicitly
./samples/semaphore-factory-resolver-di-factory-specific-adapter.ts
import { semaphoreFactory } from "./semaphore-factory-resolver-di-factory.js";
// Uses the Redis adapter
await semaphoreFactory
.use("redis")
.create("shared-resource", {
limit: 2,
})
.runOrFail(async () => {
// code to run
});
Using it with the middlewares
Because the proxy implements ISemaphoreFactoryResolver, it can be passed straight to the semaphore middleware factories:
./samples/semaphore-factory-resolver-di-factory-with-middleware.ts
import { use } from "eridu-tech/middleware";
import { withSemaphoreFactory } from "eridu-tech/semaphore/middlewares";
import { semaphoreFactory } from "./semaphore-factory-resolver-di-factory.js";
const withSemaphore = withSemaphoreFactory(semaphoreFactory);
const processFile = async (filePath: string): Promise<void> => {
// ... process the file
};
const throttledProcess = use(
processFile,
withSemaphore.use("redis")({
key: ([filePath]) => `file-path:${filePath}`,
limit: 3,
}),
);
await throttledProcess("/data/file.json");
Further information
For further information refer to eridu-tech/semaphore API docs.