Prechádzať zdrojové kódy

feat(core): Reinstate ProcessContext provider

Closes #772
Michael Bromley 4 rokov pred
rodič
commit
9e3050560e

+ 20 - 0
docs/content/docs/developer-guide/vendure-worker.md

@@ -72,3 +72,23 @@ bootstrap(config)
 
 If you are authoring a [Vendure plugin]({{< relref "/docs/plugins" >}}) to implement custom functionality, you can also make use of the worker process in order to handle long-running or computationally-demanding tasks. See the [Plugin Examples]({{< relref "plugin-examples" >}}#running-processes-on-the-worker) page for an example of this.
 
+## ProcessContext
+
+Sometimes your code may need to be aware of whether it is being run on the as part of a server or worker process. In this case you can inject the [ProcessContext]({{< relref "process-context" >}}) provider and query it like this:
+
+```TypeScript
+import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
+import { ProcessContext } from '@vendure/core';
+
+@Injectable()
+export class MyService implements OnApplicationBootstrap {
+  constructor(private processContext: ProcessContext) {}
+
+  onApplicationBootstrap() {
+    if (this.processContext.isServer) {
+      // code which will only execute when running in
+      // the server process
+    }
+  }
+}
+```

+ 3 - 8
packages/core/src/app.module.ts

@@ -1,12 +1,5 @@
-import {
-    MiddlewareConsumer,
-    Module,
-    NestMiddleware,
-    NestModule,
-    OnApplicationShutdown,
-} from '@nestjs/common';
+import { MiddlewareConsumer, Module, NestModule, OnApplicationShutdown } from '@nestjs/common';
 import { Type } from '@vendure/common/lib/shared-types';
-import { RequestHandler } from 'express';
 
 import { ApiModule } from './api/api.module';
 import { ConfigModule } from './config/config.module';
@@ -16,6 +9,7 @@ import { HealthCheckModule } from './health-check/health-check.module';
 import { I18nModule } from './i18n/i18n.module';
 import { I18nService } from './i18n/i18n.service';
 import { PluginModule } from './plugin/plugin.module';
+import { ProcessContextModule } from './process-context/process-context.module';
 import { ServiceModule } from './service/service.module';
 
 // tslint:disable-next-line:ban-types
@@ -23,6 +17,7 @@ type Middleware = Type<any> | Function;
 
 @Module({
     imports: [
+        ProcessContextModule,
         ConfigModule,
         I18nModule,
         ApiModule,

+ 3 - 0
packages/core/src/bootstrap.ts

@@ -18,6 +18,7 @@ import { validateCustomFieldsConfig } from './entity/validate-custom-fields-conf
 import { JobQueueService } from './job-queue/job-queue.service';
 import { getConfigurationFunction, getEntitiesFromPlugins } from './plugin/plugin-metadata';
 import { getPluginStartupMessages } from './plugin/plugin-utils';
+import { setProcessContext } from './process-context/process-context';
 
 export type VendureBootstrapFunction = (config: VendureConfig) => Promise<INestApplication>;
 
@@ -45,6 +46,7 @@ export async function bootstrap(userConfig: Partial<VendureConfig>): Promise<INe
     // config, so that they are available when the AppModule decorator is evaluated.
     // tslint:disable-next-line:whitespace
     const appModule = await import('./app.module');
+    setProcessContext('server');
     const { hostname, port, cors } = config.apiOptions;
     DefaultLogger.hideNestBoostrapLogs();
     const app = await NestFactory.create(appModule.AppModule, {
@@ -100,6 +102,7 @@ export async function bootstrapWorker(
     Logger.info(`Bootstrapping Vendure Worker (pid: ${process.pid})...`);
 
     const appModule = await import('./app.module');
+    setProcessContext('worker');
     DefaultLogger.hideNestBoostrapLogs();
     const workerApp = await NestFactory.createApplicationContext(appModule.AppModule, {
         logger: new Logger(),

+ 1 - 0
packages/core/src/index.ts

@@ -7,6 +7,7 @@ export * from './event-bus/index';
 export * from './health-check/index';
 export * from './job-queue/index';
 export * from './plugin/index';
+export * from './process-context/index';
 export * from './entity/index';
 export * from './data-import/index';
 export * from './service/index';

+ 1 - 0
packages/core/src/process-context/index.ts

@@ -0,0 +1 @@
+export { ProcessContext } from './process-context';

+ 10 - 0
packages/core/src/process-context/process-context.module.ts

@@ -0,0 +1,10 @@
+import { DynamicModule, Global, Module } from '@nestjs/common';
+
+import { ProcessContext } from './process-context';
+
+@Global()
+@Module({
+    providers: [ProcessContext],
+    exports: [ProcessContext],
+})
+export class ProcessContextModule {}

+ 49 - 0
packages/core/src/process-context/process-context.ts

@@ -0,0 +1,49 @@
+import { Injectable } from '@nestjs/common';
+
+type ProcessContextType = 'server' | 'worker';
+let currentContext: ProcessContextType = 'server';
+
+/**
+ * @description
+ * The ProcessContext can be injected into your providers & modules in order to know whether it
+ * is being executed in the context of the main Vendure server or the worker.
+ *
+ * @example
+ * ```TypeScript
+ * import { Injectable, OnApplicationBootstrap } from '\@nestjs/common';
+ * import { ProcessContext } from '\@vendure/core';
+ *
+ * \@Injectable()
+ * export class MyService implements OnApplicationBootstrap {
+ *   constructor(private processContext: ProcessContext) {}
+ *
+ *   onApplicationBootstrap() {
+ *     if (this.processContext.isServer) {
+ *       // code which will only execute when running in
+ *       // the server process
+ *     }
+ *   }
+ * }
+ * ```
+ *
+ * @docsCategory common
+ */
+export class ProcessContext {
+    get isServer(): boolean {
+        return currentContext === 'server';
+    }
+    get isWorker(): boolean {
+        return currentContext === 'worker';
+    }
+}
+
+/**
+ * @description
+ * Should only be called in the core bootstrap functions in order to establish
+ * the current process context.
+ *
+ * @internal
+ */
+export function setProcessContext(context: ProcessContextType) {
+    currentContext = context;
+}

+ 20 - 0
packages/dev-server/test-plugins/process-context-plugin.ts

@@ -0,0 +1,20 @@
+import { OnApplicationBootstrap, OnModuleInit } from '@nestjs/common';
+import { Logger, PluginCommonModule, ProcessContext, VendurePlugin } from '@vendure/core';
+
+/**
+ * Testing whether the ProcessContext service is giving the correct results.
+ */
+@VendurePlugin({
+    imports: [PluginCommonModule],
+})
+export class ProcessContextPlugin implements OnApplicationBootstrap, OnModuleInit {
+    constructor(private processContext: ProcessContext) {}
+
+    onApplicationBootstrap(): any {
+        Logger.warn(`onApplicationBootstrap: isServer: ${this.processContext.isServer}`);
+    }
+
+    onModuleInit(): any {
+        Logger.warn(`onModuleInit: isServer: ${this.processContext.isServer}`);
+    }
+}