Skip to content

Commit e1d7026

Browse files
committed
feat(module): add GraphileWorkerService.forRootAsync
1 parent c9da05e commit e1d7026

File tree

7 files changed

+253
-13
lines changed

7 files changed

+253
-13
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PG_CONNECTION=postgres://example:password@postgres/example

README.md

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ Why you should prefer Graphile Worker instead of [Bull](https://github.com/nestj
1616
$ npm install nest-graphile-worker
1717
```
1818

19-
Then import module
19+
## Usage
20+
21+
### Import module
22+
23+
You can use `GraphileWorkerModule.forRoot`:
2024

2125
```ts
2226
// src/app.module.ts
@@ -28,6 +32,9 @@ import { AppController } from './app.controller';
2832
imports: [
2933
GraphileWorkerModule.forRoot({
3034
connectionString: 'postgres://example:password@postgres/example',
35+
taskList: {
36+
hello: helloTask,
37+
},
3138
}),
3239
],
3340
controllers: [AppController],
@@ -36,10 +43,41 @@ import { AppController } from './app.controller';
3643
export class AppModule {}
3744
```
3845

39-
Now you can add jobs using `GraphileWorkerService`
46+
Or you can use `GraphileWorkerModule.forRootAsync`:
4047

4148
```ts
42-
import { GraphileWorkerService } from 'graphile-worker';
49+
import { GraphileWorkerModule } from '@app/graphile-worker';
50+
import { Module } from '@nestjs/common';
51+
import { ConfigModule, ConfigService } from '@nestjs/config';
52+
import { AppController } from './app.controller';
53+
import { helloTask } from './hello.task';
54+
55+
@Module({
56+
imports: [
57+
ConfigModule.forRoot(),
58+
GraphileWorkerModule.forRootAsync({
59+
imports: [ConfigModule],
60+
inject: [ConfigService],
61+
useFactory: (config: ConfigService) => ({
62+
connectionString: config.get('PG_CONNECTION'),
63+
taskList: {
64+
hello: helloTask,
65+
},
66+
}),
67+
}),
68+
],
69+
controllers: [AppController],
70+
providers: [],
71+
})
72+
export class AppModule {}
73+
```
74+
75+
## Create jobs
76+
77+
You may use `GraphileWorkerService`:
78+
79+
```ts
80+
import { GraphileWorkerService } from '@app/graphile-worker';
4381
import { Controller, HttpCode, Post } from '@nestjs/common';
4482

4583
@Controller()
@@ -49,12 +87,26 @@ export class AppController {
4987
@Post()
5088
@HttpCode(201)
5189
async addJob() {
52-
await this.graphileWorker.quickAddJob('test', { hello: 'world' });
90+
await this.graphileWorker.addJob('hello', { hello: 'world' });
91+
}
92+
93+
@Post('bulk')
94+
@HttpCode(201)
95+
async addJobs() {
96+
const jobs: Array<{ identifier: string; payload?: unknown }> = new Array(
97+
100,
98+
)
99+
.fill(undefined)
100+
.map((_, i) => ({ identifier: 'hello', payload: { hello: i } }));
101+
102+
return this.graphileWorker.addJobs(jobs);
53103
}
54104
}
55105
```
56106

57-
Also you can run worker in bacground in `main.ts` file:
107+
## Start runner
108+
109+
Add `GraphileWorkerService.run` in `main.ts` file:
58110

59111
```ts
60112
import { GraphileWorkerService } from '@app/graphile-worker';
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { FactoryProvider, ModuleMetadata } from '@nestjs/common';
2+
import { RunnerOptions } from 'graphile-worker';
3+
4+
export type GraphileWorkerConfiguration = RunnerOptions;
5+
6+
export interface GraphileWorkerConfigurationFactory {
7+
createSharedConfiguration():
8+
| Promise<GraphileWorkerConfiguration>
9+
| GraphileWorkerConfiguration;
10+
}
11+
12+
export interface GraphileWorkerAsyncConfiguration
13+
extends Pick<ModuleMetadata, 'imports'> {
14+
/**
15+
* Existing Provider to be used.
16+
*/
17+
// useExisting?: Type<GraphileWorkerConfigurationFactory>;
18+
19+
/**
20+
* Type (class name) of provider (instance to be registered and injected).
21+
*/
22+
// useClass?: Type<GraphileWorkerConfigurationFactory>;
23+
24+
/**
25+
* Factory function that returns an instance of the provider to be injected.
26+
*/
27+
useFactory?: (
28+
...args: any[]
29+
) => Promise<GraphileWorkerConfiguration> | GraphileWorkerConfiguration;
30+
31+
/**
32+
* Optional list of providers to be injected into the context of the Factory function.
33+
*/
34+
inject?: FactoryProvider['inject'];
35+
}

libs/graphile-worker/src/graphile-worker.module.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { DynamicModule, Module, Provider } from '@nestjs/common';
2-
import { RunnerOptions } from 'graphile-worker';
2+
import {
3+
GraphileWorkerAsyncConfiguration,
4+
GraphileWorkerConfiguration,
5+
GraphileWorkerConfigurationFactory,
6+
} from './config.interface';
37
import { GraphileWorkerService } from './graphile-worker.service';
48

59
export const GRAPHILE_WORKER_TOKEN = Symbol.for('NestJsGraphileWorker');
@@ -9,10 +13,13 @@ export const GRAPHILE_WORKER_TOKEN = Symbol.for('NestJsGraphileWorker');
913
exports: [GraphileWorkerService],
1014
})
1115
export class GraphileWorkerModule {
12-
static forRoot(options: RunnerOptions): DynamicModule {
16+
/**
17+
* Registers a globally available `GraphileWorkerService`.
18+
*/
19+
static forRoot(config: GraphileWorkerConfiguration): DynamicModule {
1320
const graphileWorkerService: Provider = {
1421
provide: GraphileWorkerService,
15-
useValue: new GraphileWorkerService(options),
22+
useValue: new GraphileWorkerService(config),
1623
};
1724

1825
return {
@@ -22,4 +29,51 @@ export class GraphileWorkerModule {
2229
exports: [graphileWorkerService],
2330
};
2431
}
32+
33+
static forRootAsync(
34+
asyncConfig: GraphileWorkerAsyncConfiguration,
35+
): DynamicModule {
36+
const providers = this.createAsyncSharedConfigurationProviders(asyncConfig);
37+
38+
return {
39+
global: true,
40+
module: GraphileWorkerModule,
41+
imports: asyncConfig.imports,
42+
providers,
43+
exports: providers,
44+
};
45+
}
46+
47+
private static createAsyncSharedConfigurationProviders(
48+
options: GraphileWorkerAsyncConfiguration,
49+
): Provider[] {
50+
return [this.createAsyncSharedConfigurationProvider(options)];
51+
}
52+
53+
private static createAsyncSharedConfigurationProvider(
54+
options: GraphileWorkerAsyncConfiguration,
55+
): Provider {
56+
if (options.useFactory) {
57+
return {
58+
provide: GraphileWorkerService,
59+
useFactory: async (...args: any[]) => {
60+
const configuration = await options.useFactory(...args);
61+
return new GraphileWorkerService(configuration);
62+
},
63+
inject: options.inject || [],
64+
};
65+
}
66+
67+
return {
68+
provide: GraphileWorkerService,
69+
useFactory: async (
70+
optionsFactory: GraphileWorkerConfigurationFactory,
71+
) => {
72+
const configuration = await optionsFactory.createSharedConfiguration();
73+
74+
return new GraphileWorkerService(configuration);
75+
},
76+
inject: options.inject,
77+
};
78+
}
2579
}

package-lock.json

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"dependencies": {
2424
"@nestjs/common": "^8.0.0",
25+
"@nestjs/config": "^1.0.1",
2526
"@nestjs/core": "^8.0.0",
2627
"@nestjs/platform-express": "^8.0.0",
2728
"graphile-worker": "^0.11.4",

0 commit comments

Comments
 (0)