UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

136 lines (134 loc) 5.37 kB
import { BehaviorSubject, merge, of, ReplaySubject, zip } from 'rxjs'; import { catchError, mergeMap, map, take } from 'rxjs/operators'; import { LogLevel } from '../../diagnostics/log-level'; import { Logging } from '../../diagnostics/logging'; /** * Defines an abstraction for working with a set of workers given a designated extension target */ export class WorkerSet { extensionBroker; extensionTarget; mapArguments; /** * The source name to use when logging about this service */ get logSourceName() { return 'WorkerSet'; } /** * Observable to track the creation of our workers */ workers; /** * Determine if workers were initialized successfully */ workersInitializedSubject = new BehaviorSubject(false); workersInitialized = this.workersInitializedSubject.asObservable(); get isWorkersInitialized() { return this.workersInitializedSubject.value; } /** * instantiates a new instance of the AzureCenterService service * @param extensionBroker the extension broker instance * @param extensionTarget the extension target id we want to get workers for * @param mapArguments a function that maps different versions of worker arguments * based on the the versions implemented by a worker @optional @deprecated */ constructor(extensionBroker, extensionTarget, mapArguments) { this.extensionBroker = extensionBroker; this.extensionTarget = extensionTarget; this.mapArguments = mapArguments; this.workers = new ReplaySubject(); } /** * Initializes the workers */ initializeWorkers() { this.extensionBroker.getTargetExtensions(this.extensionTarget).pipe(mergeMap(fulfillments => { const workersObservables = Object.keys(fulfillments).map(entryPointId => this.extensionBroker.createWorker(entryPointId, this.extensionTarget)); if (workersObservables.length === 0) { // This is a valid case were the workers should be considered to be initialized, // but no workers exist that target this extension. return of([]); } return zip(...workersObservables); }), take(1)).subscribe({ next: workers => { this.workers.next(workers); this.workersInitializedSubject.next(true); }, error: error => { Logging.log({ level: LogLevel.Critical, message: 'Failed to initialize workers', source: this.logSourceName, params: { error: error } }); this.workers.next([]); } }); } /** * Destroys the workers */ destroyWorkers() { this.workers.pipe(mergeMap(workers => zip(...(workers.map(w => w.destroy())))), take(1)).subscribe(); } /** * Calls a method on each worker in and emits when all workers to respond */ all(method, ...args) { return this.prepareCalls(method, args).pipe(mergeMap(calls => zip(...calls))); } /** * Calls a method on each worker in and emits when each worker responds */ each(method, ...args) { return this.prepareCalls(method, args).pipe(mergeMap(calls => merge(...calls))); } /** * Calls a function on the applicable workers */ prepareCalls(method, ...args) { return this.workers.pipe(map(workers => { // find workers that support the version of the method we want const workerCalls = workers // map all our worker instances into a set of supported function calls .map(w => { const methodVersion = w.extenderDefinition.methodVersions[method]; if (MsftSme.isNullOrUndefined(methodVersion)) { // this worker does not support this method at all return null; } // if this worker implements the mapArguments method then treat it like the old version of this method let mappedArguments = args; if (this.mapArguments) { mappedArguments = this.mapArguments(method, methodVersion, args[0]); if (MsftSme.isNullOrUndefined(mappedArguments)) { // this worker does not support a version this implementation can deal with return null; } } return w.call(method, methodVersion, ...mappedArguments).pipe(map(methodReturn => { const workerResult = { worker: w, returnValue: methodReturn }; return workerResult; }), catchError((error) => { const workerResult = { worker: w, error: error }; return of(workerResult); })); }) // ignore workers that dont support this method .filter(w => !!w); return workerCalls; })); } } //# sourceMappingURL=worker-set.js.map