feat(housekeeping): orchestrate partial providers
This commit is contained in:
1 parent
60968409aa
commit
4c399873d1
4 files changed
+306
No files matched your search
@@ -0,0 +1,55 @@
|
||||
import type {
|
||||
HousekeepingCapabilityContext,
|
||||
HousekeepingErrorCode,
|
||||
} from "../contracts";
|
||||
import { createCorrelationId } from "../correlation";
|
||||
import { type HousekeepingProvider, runProvider } from "./run-provider";
|
||||
|
||||
export interface ProviderPolicy<T> {
|
||||
timeoutMs: number;
|
||||
perProviderLimit: number;
|
||||
combinedLimit: number;
|
||||
sort(items: readonly T[]): readonly T[];
|
||||
dedupeKey(item: T): string;
|
||||
}
|
||||
|
||||
export interface ProviderBatchResult<T> {
|
||||
items: readonly T[];
|
||||
errors: readonly { providerId: string; code: HousekeepingErrorCode }[];
|
||||
correlationId: string;
|
||||
}
|
||||
|
||||
export async function orchestrateProviders<T>(
|
||||
providers: readonly HousekeepingProvider<T>[],
|
||||
context: HousekeepingCapabilityContext,
|
||||
policy: ProviderPolicy<T>,
|
||||
): Promise<ProviderBatchResult<T>> {
|
||||
const providerResults = await Promise.all(
|
||||
providers.map((provider) =>
|
||||
runProvider(provider, context, policy.timeoutMs),
|
||||
),
|
||||
);
|
||||
const items: T[] = [];
|
||||
const seen = new Set<string>();
|
||||
const errors: { providerId: string; code: HousekeepingErrorCode }[] = [];
|
||||
|
||||
for (const result of providerResults) {
|
||||
if (result.error !== undefined) {
|
||||
errors.push({ providerId: result.providerId, code: result.error });
|
||||
}
|
||||
|
||||
for (const item of result.items.slice(0, policy.perProviderLimit)) {
|
||||
if (items.length >= policy.combinedLimit) break;
|
||||
const key = policy.dedupeKey(item);
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
items: policy.sort(items),
|
||||
errors,
|
||||
correlationId: createCorrelationId(),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user