@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
136 lines (134 loc) • 5.37 kB
JavaScript
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