Skip to content

Commit 8066ce9

Browse files
committed
feat(): accessing IoC container
1 parent 3063379 commit 8066ce9

File tree

9 files changed

+127
-0
lines changed

9 files changed

+127
-0
lines changed

src/app.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import { AppController } from './app.controller'
33
import { AppService } from './app.service'
44
import { CoffeesModule } from './coffees/coffees.module'
55
import { DevtoolsModule } from '@nestjs/devtools-integration'
6+
import { SchedulerModule } from './scheduler/scheduler.module';
7+
import { CronModule } from './cron/cron.module';
68

79
@Module({
810
imports: [
911
CoffeesModule,
1012
DevtoolsModule.register({
1113
http: process.env.NODE_ENV !== 'production',
1214
}),
15+
SchedulerModule,
16+
CronModule,
1317
],
1418
controllers: [AppController],
1519
providers: [AppService],

src/cron/cron.module.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Module } from '@nestjs/common';
2+
import { CronService } from './cron.service';
3+
4+
@Module({
5+
providers: [CronService]
6+
})
7+
export class CronModule {}

src/cron/cron.service.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { CronService } from './cron.service';
3+
4+
describe('CronService', () => {
5+
let service: CronService;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
providers: [CronService],
10+
}).compile();
11+
12+
service = module.get<CronService>(CronService);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(service).toBeDefined();
17+
});
18+
});

src/cron/cron.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Interval } from 'src/scheduler/decorators/interval.decorator'
2+
import { IntervalHost } from '../scheduler/decorators/interval-host.decorator'
3+
4+
@IntervalHost
5+
export class CronService {
6+
@Interval(10000)
7+
everySecond() {
8+
console.log('This will be logged every 10 seconds!')
9+
}
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { SetMetadata } from '@nestjs/common'
2+
3+
export const INTERVAL_HOST_KEY = 'INTERVAL_HOST_KEY'
4+
export const IntervalHost: ClassDecorator = SetMetadata(INTERVAL_HOST_KEY, true)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { SetMetadata } from '@nestjs/common'
2+
3+
export const INTERVAL_KEY = 'INTERVAL_KEY'
4+
export const Interval = (ms: number) => SetMetadata(INTERVAL_KEY, ms)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { DiscoveryService, Reflector, MetadataScanner } from '@nestjs/core'
2+
import { IntervalScheduler } from './interval.scheduler'
3+
4+
describe('IntervalScheduler', () => {
5+
it('should be defined', () => {
6+
const discoveryService = {} as DiscoveryService
7+
const reflector = {} as Reflector
8+
const metadataScanner = {} as MetadataScanner
9+
10+
expect(
11+
new IntervalScheduler(discoveryService, reflector, metadataScanner),
12+
).toBeDefined()
13+
})
14+
})
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {
2+
Injectable,
3+
OnApplicationBootstrap,
4+
OnApplicationShutdown,
5+
} from '@nestjs/common'
6+
import { DiscoveryService, MetadataScanner, Reflector } from '@nestjs/core'
7+
import { INTERVAL_HOST_KEY } from './decorators/interval-host.decorator'
8+
import { INTERVAL_KEY } from './decorators/interval.decorator'
9+
10+
@Injectable()
11+
export class IntervalScheduler
12+
implements OnApplicationBootstrap, OnApplicationShutdown
13+
{
14+
private readonly intervals: NodeJS.Timeout[] = []
15+
16+
constructor(
17+
private readonly discoveryService: DiscoveryService,
18+
private readonly reflector: Reflector,
19+
private readonly metadataScanner: MetadataScanner,
20+
) {}
21+
22+
onApplicationBootstrap() {
23+
const providers = this.discoveryService.getProviders()
24+
providers.forEach((wrapper) => {
25+
const { instance } = wrapper
26+
27+
const prototype = instance && Object.getPrototypeOf(instance)
28+
if (!instance || !prototype) {
29+
return
30+
}
31+
32+
const isIntervalHost =
33+
this.reflector.get(INTERVAL_HOST_KEY, instance.constructor) ?? false
34+
35+
if (!isIntervalHost) {
36+
return
37+
}
38+
39+
const methodKeys = this.metadataScanner.getAllMethodNames(prototype)
40+
41+
methodKeys.forEach((methodKey) => {
42+
const interval = this.reflector.get(INTERVAL_KEY, instance[methodKey])
43+
44+
if (interval === undefined) {
45+
return
46+
}
47+
48+
const intervalRef = setInterval(() => instance[methodKey](), interval)
49+
this.intervals.push(intervalRef)
50+
})
51+
})
52+
}
53+
54+
onApplicationShutdown(signal?: string) {
55+
this.intervals.forEach((intervalRef) => clearInterval(intervalRef))
56+
}
57+
}

src/scheduler/scheduler.module.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Module } from '@nestjs/common'
2+
import { DiscoveryModule } from '@nestjs/core'
3+
import { IntervalScheduler } from './interval.scheduler'
4+
5+
@Module({
6+
imports: [DiscoveryModule],
7+
providers: [IntervalScheduler],
8+
})
9+
export class SchedulerModule {}

0 commit comments

Comments
 (0)