diff --git a/src/utils/config/__tests__/global-ref.node.ts b/src/utils/__tests__/global-ref.node.ts similarity index 88% rename from src/utils/config/__tests__/global-ref.node.ts rename to src/utils/__tests__/global-ref.node.ts index fcdf28215..88cf95328 100644 --- a/src/utils/config/__tests__/global-ref.node.ts +++ b/src/utils/__tests__/global-ref.node.ts @@ -23,6 +23,11 @@ describe('GlobalRef', () => { expect(globalRef.value).toBeUndefined(); }); + it('should return default value if value is not set and default value is passed', () => { + const globalRef = new GlobalRef('unique-name', 100); + expect(globalRef.value).toBe(100); + }); + it('should handle different types of values', () => { const stringRef = new GlobalRef('string-unique-name'); stringRef.value = 'test string'; diff --git a/src/utils/config/global-configs-ref.ts b/src/utils/config/global-configs-ref.ts index 33c7ae87b..65b664835 100644 --- a/src/utils/config/global-configs-ref.ts +++ b/src/utils/config/global-configs-ref.ts @@ -1,5 +1,6 @@ +import GlobalRef from '../global-ref'; + import { type LoadedConfigs } from './config.types'; -import GlobalRef from './global-ref'; const globalConfigRef = new GlobalRef('cadence-config'); const setLoadedGlobalConfigs = (c: LoadedConfigs): void => { diff --git a/src/utils/config/global-ref.ts b/src/utils/global-ref.ts similarity index 62% rename from src/utils/config/global-ref.ts rename to src/utils/global-ref.ts index 48f855592..c50c752fa 100644 --- a/src/utils/config/global-ref.ts +++ b/src/utils/global-ref.ts @@ -1,8 +1,10 @@ export default class GlobalRef { private readonly sym: symbol; - constructor(uniqueName: string) { + constructor(uniqueName: string, defaultValue?: T) { this.sym = Symbol.for(uniqueName); + const g = global as any; + if (g[this.sym] === undefined) g[this.sym] = defaultValue; } get value() { diff --git a/src/utils/grpc/grpc-client.ts b/src/utils/grpc/grpc-client.ts index b99475e3f..75ea765d5 100644 --- a/src/utils/grpc/grpc-client.ts +++ b/src/utils/grpc/grpc-client.ts @@ -30,22 +30,21 @@ import { type TerminateWorkflowExecutionRequest__Input } from '@/__generated__/p import { type TerminateWorkflowExecutionResponse } from '@/__generated__/proto-ts/uber/cadence/api/v1/TerminateWorkflowExecutionResponse'; import { type UpdateDomainRequest__Input } from '@/__generated__/proto-ts/uber/cadence/api/v1/UpdateDomainRequest'; import { type UpdateDomainResponse } from '@/__generated__/proto-ts/uber/cadence/api/v1/UpdateDomainResponse'; +import { type ClusterConfig } from '@/config/dynamic/resolvers/clusters.types'; import grpcServiceConfigurations from '../../config/grpc/grpc-services-config'; import getConfigValue from '../config/get-config-value'; +import GlobalRef from '../global-ref'; import GRPCService, { type GRPCMetadata, type GRPCRequestConfig, } from './grpc-service'; - -type ClusterServices = Record< - string, - Record< - 'adminService' | 'domainService' | 'visibilityService' | 'workflowService', - GRPCService - > +type ClusterService = Record< + 'adminService' | 'domainService' | 'visibilityService' | 'workflowService', + GRPCService >; +type ClustersServices = Record; export type GRPCClusterMethods = { archivedWorkflows: ( payload: ListArchivedWorkflowExecutionsRequest__Input @@ -100,50 +99,70 @@ export type GRPCClusterMethods = { ) => Promise; }; -const getClusterServices = async () => { - const CLUSTERS_CONFIGS = await getConfigValue('CLUSTERS'); - return CLUSTERS_CONFIGS.reduce((result, c) => { - const requestConfig: GRPCRequestConfig = { - serviceName: c.grpc.serviceName, - metadata: c.grpc.metadata, - }; +// cache services instances +const clusterServicesMapGlobalRef = new GlobalRef( + 'cluster-services-map', + {} +); +const clusterServicesMap: ClustersServices = clusterServicesMapGlobalRef.value; + +const getClusterServices = async (c: ClusterConfig) => { + if (clusterServicesMap[c.clusterName]) { + return clusterServicesMap[c.clusterName]; + } + + const requestConfig: GRPCRequestConfig = { + serviceName: c.grpc.serviceName, + metadata: c.grpc.metadata, + }; - const adminService = new GRPCService({ - peer: c.grpc.peer, - requestConfig, - ...grpcServiceConfigurations.adminServiceConfig, - }); - const domainService = new GRPCService({ - peer: c.grpc.peer, - requestConfig, - ...grpcServiceConfigurations.domainServiceConfig, - }); - const visibilityService = new GRPCService({ - peer: c.grpc.peer, - requestConfig, - ...grpcServiceConfigurations.visibilityServiceConfig, - }); - const workflowService = new GRPCService({ - peer: c.grpc.peer, - requestConfig, - ...grpcServiceConfigurations.workflowServiceConfig, - }); + const adminService = new GRPCService({ + peer: c.grpc.peer, + requestConfig, + ...grpcServiceConfigurations.adminServiceConfig, + }); + const domainService = new GRPCService({ + peer: c.grpc.peer, + requestConfig, + ...grpcServiceConfigurations.domainServiceConfig, + }); + const visibilityService = new GRPCService({ + peer: c.grpc.peer, + requestConfig, + ...grpcServiceConfigurations.visibilityServiceConfig, + }); + const workflowService = new GRPCService({ + peer: c.grpc.peer, + requestConfig, + ...grpcServiceConfigurations.workflowServiceConfig, + }); - result[c.clusterName] = { - adminService, - domainService, - visibilityService, - workflowService, - }; - return result; - }, {} as ClusterServices); + const services: ClusterService = { + adminService, + domainService, + visibilityService, + workflowService, + }; + // add service to cache (clusterServicesMap) + clusterServicesMap[c.clusterName] = services; + return services; +}; + +const getAllClustersServices = async () => { + const CLUSTERS_CONFIGS = await getConfigValue('CLUSTERS'); + const clustersServices: ClustersServices = {}; + + for (const c of CLUSTERS_CONFIGS) { + clustersServices[c.clusterName] = await getClusterServices(c); + } + return clustersServices; }; const getClusterServicesMethods = async ( c: string, metadata?: GRPCMetadata ): Promise => { - const clusterServices = await getClusterServices(); + const clusterServices = await getAllClustersServices(); const { visibilityService, adminService, domainService, workflowService } = clusterServices[c];