Skip to main content
Version: 4.0.0

One-time Execution

@midwayjs/one-shot is a one-shot script framework that only provides a Framework. It is suitable for running tasks once with IoC-managed dependencies.

Related information:

Description
Available for standard app
Available for Serverless
Available for integrated
Includes standalone core
Includes standalone logger

Install

Install the one-shot component dependency in an existing project.

$ npm i @midwayjs/one-shot@4  --save

Or add the following dependency to package.json, then reinstall.

{
"dependencies": {
"@midwayjs/one-shot": "^4.0.0"
}
}

Enable the component

Import the component in the entry configuration.

// src/configuration.ts
import { Configuration } from '@midwayjs/core';
import * as oneShot from '@midwayjs/one-shot';

@Configuration({
imports: [oneShot],
})
export class MainConfiguration {}

Run in lifecycle

No extra Runner is required. It's recommended to execute one-shot logic in onServerReady.

// src/configuration.ts
import { Configuration, Inject } from '@midwayjs/core';
import * as oneShot from '@midwayjs/one-shot';
import { ScriptService } from './service/script';

@Configuration({
imports: [oneShot],
})
export class MainConfiguration {
@Inject()
scriptService: ScriptService;

async onServerReady() {
await this.scriptService.runOnce();
}
}

When request scope is needed

If your script needs request-scope services, use the framework runScript API with a fixed runner class. The framework will create a context for this execution and run the middleware/filter chain.

// src/script/syncUser.ts
import { Provide } from '@midwayjs/core';
import { OneShotRunner, Context } from '@midwayjs/one-shot';

@Provide()
export class SyncUserScript implements OneShotRunner<{ id: number }, void> {
async run(payload?: { id: number }, ctx?: Context) {
// use payload / ctx
void payload;
void ctx;
}
}
// src/configuration.ts
import { Configuration, Inject } from '@midwayjs/core';
import * as oneShot from '@midwayjs/one-shot';
import { Framework } from '@midwayjs/one-shot';
import { SyncUserScript } from './script/syncUser';

@Configuration({
imports: [oneShot],
})
export class MainConfiguration {
@Inject()
framework: Framework;

async onServerReady() {
await this.framework.runScript(SyncUserScript, { id: 42 });
}
}

Logger

By default, the component registers a logger named oneShotLogger, which writes to midway-one-shot.log.

You can inject and use it in your script service via @Logger('oneShotLogger'), for example:

import { Logger, ILogger } from '@midwayjs/core';

export class ScriptService {
@Logger('oneShotLogger')
logger: ILogger;

async runOnce() {
this.logger.info('run one-shot task');
}
}

If you want to customize the log file name or level, override midwayLogger.clients.oneShotLogger in your application config:

// src/config/config.default.ts
export default {
midwayLogger: {
clients: {
oneShotLogger: {
fileLogName: 'my-one-shot.log',
level: 'info',
},
},
},
};