Skip to content

Commit c77654f

Browse files
committed
transportcontext is not required
1 parent 7c4daa1 commit c77654f

File tree

6 files changed

+59
-57
lines changed

6 files changed

+59
-57
lines changed

packages/fusion-runtime/src/executor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function getExecutorForUnifiedGraph<TContext>(
3434
() => unifiedGraphManager.getContext(execReq.context),
3535
(context) => {
3636
function handleExecutor(executor: Executor) {
37-
opts?.transportContext.log.debug(
37+
opts?.transportContext?.log.debug(
3838
'Executing request on unified graph',
3939
() => print(execReq.document),
4040
);
@@ -50,7 +50,7 @@ export function getExecutorForUnifiedGraph<TContext>(
5050
return handleMaybePromise(
5151
() => unifiedGraphManager.getUnifiedGraph(),
5252
(unifiedGraph) => {
53-
opts?.transportContext.log.debug(
53+
opts?.transportContext?.log.debug(
5454
'Executing request on unified graph',
5555
() => print(execReq.document),
5656
);
@@ -70,7 +70,7 @@ export function getExecutorForUnifiedGraph<TContext>(
7070
enumerable: true,
7171
get() {
7272
return function unifiedGraphExecutorDispose() {
73-
opts?.transportContext.log.debug('Disposing unified graph executor');
73+
opts?.transportContext?.log.debug('Disposing unified graph executor');
7474
return unifiedGraphManager[DisposableSymbols.asyncDispose]();
7575
};
7676
},

packages/fusion-runtime/src/federation/supergraph.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ export const handleFederationSupergraph: UnifiedGraphHandler = function ({
158158
onDelegateHooks,
159159
additionalTypeDefs: additionalTypeDefsFromConfig = [],
160160
additionalResolvers: additionalResolversFromConfig = [],
161-
log: rootLog,
161+
// no logger was provided, use a muted logger for consistency across plugin hooks
162+
log: rootLog = new Logger({ level: false }),
162163
}: UnifiedGraphHandlerOpts): UnifiedGraphHandlerResult {
163164
const additionalTypeDefs = [...asArray(additionalTypeDefsFromConfig)];
164165
const additionalResolvers = [...asArray(additionalResolversFromConfig)];

packages/fusion-runtime/src/unifiedGraphManager.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export interface UnifiedGraphHandlerOpts {
6969
onDelegationPlanHooks?: OnDelegationPlanHook<any>[];
7070
onDelegationStageExecuteHooks?: OnDelegationStageExecuteHook<any>[];
7171
onDelegateHooks?: OnDelegateHook<unknown>[];
72-
log: Logger;
72+
log?: Logger;
7373
}
7474

7575
export interface UnifiedGraphHandlerResult {
@@ -81,7 +81,7 @@ export interface UnifiedGraphHandlerResult {
8181

8282
export interface UnifiedGraphManagerOptions<TContext> {
8383
getUnifiedGraph(
84-
ctx: TransportContext,
84+
ctx: TransportContext | undefined,
8585
): MaybePromise<GraphQLSchema | string | DocumentNode>;
8686
// Handle the unified graph by any specification
8787
handleUnifiedGraph?: UnifiedGraphHandler;
@@ -93,7 +93,7 @@ export interface UnifiedGraphManagerOptions<TContext> {
9393
additionalResolvers?:
9494
| IResolvers<unknown, TContext>
9595
| IResolvers<unknown, TContext>[];
96-
transportContext: TransportContext;
96+
transportContext?: TransportContext;
9797
onSubgraphExecuteHooks?: OnSubgraphExecuteHook<TContext>[];
9898
// TODO: Will be removed later once we get rid of v0
9999
onDelegateHooks?: OnDelegateHook<unknown>[];
@@ -156,7 +156,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
156156
this.onDelegationStageExecuteHooks =
157157
opts?.onDelegationStageExecuteHooks || [];
158158
if (opts.pollingInterval != null) {
159-
opts.transportContext.log.debug(
159+
opts.transportContext?.log.debug(
160160
`Starting polling to Supergraph with interval ${millisecondsToStr(opts.pollingInterval)}`,
161161
);
162162
}
@@ -169,14 +169,14 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
169169
this.lastLoadTime != null &&
170170
Date.now() - this.lastLoadTime >= this.opts.pollingInterval
171171
) {
172-
this.opts?.transportContext.log.debug(`Polling Supergraph`);
172+
this.opts?.transportContext?.log.debug(`Polling Supergraph`);
173173
this.polling$ = handleMaybePromise(
174174
() => this.getAndSetUnifiedGraph(),
175175
() => {
176176
this.polling$ = undefined;
177177
},
178178
(err) => {
179-
this.opts.transportContext.log.error(
179+
this.opts.transportContext?.log.error(
180180
err,
181181
'Failed to poll Supergraph',
182182
);
@@ -186,19 +186,20 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
186186
}
187187
if (!this.unifiedGraph) {
188188
if (!this.initialUnifiedGraph$) {
189-
this.opts?.transportContext.log.debug(
189+
this.opts?.transportContext?.log.debug(
190190
'Fetching the initial Supergraph',
191191
);
192-
if (this.opts.transportContext.cache) {
193-
this.opts.transportContext.log.debug(
192+
if (this.opts.transportContext?.cache) {
193+
this.opts.transportContext?.log.debug(
194194
{ key: UNIFIEDGRAPH_CACHE_KEY },
195195
'Searching for Supergraph in cache...',
196196
);
197197
this.initialUnifiedGraph$ = handleMaybePromise(
198-
() => this.opts.transportContext.cache?.get(UNIFIEDGRAPH_CACHE_KEY),
198+
() =>
199+
this.opts.transportContext?.cache?.get(UNIFIEDGRAPH_CACHE_KEY),
199200
(cachedUnifiedGraph) => {
200201
if (cachedUnifiedGraph) {
201-
this.opts.transportContext.log.debug(
202+
this.opts.transportContext?.log.debug(
202203
{ key: UNIFIEDGRAPH_CACHE_KEY },
203204
'Found Supergraph in cache',
204205
);
@@ -217,7 +218,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
217218
() => this.initialUnifiedGraph$!,
218219
(v) => {
219220
this.initialUnifiedGraph$ = undefined;
220-
this.opts.transportContext.log.debug(
221+
this.opts.transportContext?.log.debug(
221222
{ key: UNIFIEDGRAPH_CACHE_KEY },
222223
'Initial Supergraph fetched',
223224
);
@@ -241,7 +242,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
241242
this.lastLoadedUnifiedGraph != null &&
242243
compareSchemas(loadedUnifiedGraph, this.lastLoadedUnifiedGraph)
243244
) {
244-
this.opts.transportContext.log.debug(
245+
this.opts.transportContext?.log.debug(
245246
'Supergraph has not been changed, skipping...',
246247
);
247248
this.lastLoadTime = Date.now();
@@ -268,18 +269,18 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
268269
// 60 seconds making sure the unifiedgraph is not kept forever
269270
// NOTE: we default to 60s because Cloudflare KV TTL does not accept anything less
270271
60;
271-
this.opts.transportContext.log.debug(
272+
this.opts.transportContext?.log.debug(
272273
{ ttl, key: UNIFIEDGRAPH_CACHE_KEY },
273274
'Caching Supergraph',
274275
);
275276
const logCacheSetError = (err: unknown) => {
276-
this.opts.transportContext.log.debug(
277+
this.opts.transportContext?.log.debug(
277278
{ err, ttl, key: UNIFIEDGRAPH_CACHE_KEY },
278279
'Unable to cache Supergraph',
279280
);
280281
};
281282
try {
282-
const cacheSet$ = this.opts.transportContext.cache.set(
283+
const cacheSet$ = this.opts.transportContext?.cache.set(
283284
UNIFIEDGRAPH_CACHE_KEY,
284285
serializedUnifiedGraph,
285286
{ ttl },
@@ -292,7 +293,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
292293
logCacheSetError(e);
293294
}
294295
} catch (err: any) {
295-
this.opts.transportContext.log.error(
296+
this.opts.transportContext?.log.error(
296297
err,
297298
'Failed to initiate caching of Supergraph',
298299
);
@@ -320,7 +321,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
320321
onDelegationPlanHooks: this.onDelegationPlanHooks,
321322
onDelegationStageExecuteHooks: this.onDelegationStageExecuteHooks,
322323
onDelegateHooks: this.opts.onDelegateHooks,
323-
log: this.opts.transportContext.log,
324+
log: this.opts.transportContext?.log,
324325
});
325326
const transportExecutorStack = new AsyncDisposableStack();
326327
const onSubgraphExecute = getOnSubgraphExecute({
@@ -362,7 +363,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
362363
},
363364
},
364365
);
365-
this.opts.transportContext.log.debug(
366+
this.opts.transportContext?.log.debug(
366367
'Supergraph has been changed, updating...',
367368
);
368369
}
@@ -374,7 +375,7 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
374375
},
375376
(err) => {
376377
this.disposeReason = undefined;
377-
this.opts.transportContext.log.error(
378+
this.opts.transportContext?.log.error(
378379
err,
379380
'Failed to dispose the existing transports and executors',
380381
);
@@ -394,11 +395,11 @@ export class UnifiedGraphManager<TContext> implements AsyncDisposable {
394395

395396
private getAndSetUnifiedGraph(): MaybePromise<GraphQLSchema> {
396397
return handleMaybePromise(
397-
() => this.opts.getUnifiedGraph(this.opts.transportContext || {}),
398+
() => this.opts.getUnifiedGraph(this.opts.transportContext),
398399
(loadedUnifiedGraph: string | GraphQLSchema | DocumentNode) =>
399400
this.handleLoadedUnifiedGraph(loadedUnifiedGraph),
400401
(err) => {
401-
this.opts.transportContext.log.error(err, 'Failed to load Supergraph');
402+
this.opts.transportContext?.log.error(err, 'Failed to load Supergraph');
402403
this.lastLoadTime = Date.now();
403404
this.disposeReason = undefined;
404405
this.polling$ = undefined;

packages/fusion-runtime/src/utils.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getInstrumented } from '@envelop/instrumentation';
2-
import type { Logger } from '@graphql-hive/logger';
2+
import { LegacyLogger, Logger } from '@graphql-hive/logger';
33
import { loggerForRequest } from '@graphql-hive/logger/request';
44
import {
55
defaultPrintFn,
@@ -108,15 +108,15 @@ function getTransportExecutor({
108108
transports = defaultTransportsGetter,
109109
getDisposeReason,
110110
}: {
111-
transportContext: TransportContext;
111+
transportContext: TransportContext | undefined;
112112
transportEntry: TransportEntry;
113113
subgraphName?: string;
114114
subgraph: GraphQLSchema;
115115
transports?: Transports;
116116
getDisposeReason?: () => GraphQLError | undefined;
117117
}): MaybePromise<Executor> {
118118
const kind = transportEntry?.kind || '';
119-
transportContext.log.debug(`Loading transport "${kind}"`);
119+
transportContext?.log.debug(`Loading transport "${kind}"`);
120120
return handleMaybePromise(
121121
() =>
122122
typeof transports === 'function' ? transports(kind) : transports[kind],
@@ -143,6 +143,11 @@ function getTransportExecutor({
143143
`Transport "${kind}" "getSubgraphExecutor" is not a function`,
144144
);
145145
}
146+
const log =
147+
transportContext?.log ||
148+
// if the logger is not provided by the context, create a new silent one just for consistency in the hooks
149+
new Logger({ level: false });
150+
const logger = transportContext?.logger || LegacyLogger.from(log);
146151
return getSubgraphExecutor({
147152
subgraphName,
148153
subgraph,
@@ -159,6 +164,8 @@ function getTransportExecutor({
159164
},
160165
getDisposeReason,
161166
...transportContext,
167+
log,
168+
logger,
162169
});
163170
},
164171
);
@@ -186,7 +193,7 @@ export function getOnSubgraphExecute({
186193
}: {
187194
onSubgraphExecuteHooks: OnSubgraphExecuteHook[];
188195
transports?: Transports;
189-
transportContext: TransportContext;
196+
transportContext?: TransportContext;
190197
transportEntryMap: Record<string, TransportEntry>;
191198
getSubgraphSchema(subgraphName: string): GraphQLSchema;
192199
transportExecutorStack: AsyncDisposableStack;
@@ -203,18 +210,20 @@ export function getOnSubgraphExecute({
203210
let executor: Executor | undefined = subgraphExecutorMap.get(subgraphName);
204211
// If the executor is not initialized yet, initialize it
205212
if (executor == null) {
206-
let log = executionRequest.context?.request
207-
? loggerForRequest(
208-
transportContext.log,
209-
executionRequest.context.request,
210-
)
211-
: transportContext.log;
212-
if (subgraphName) {
213-
log = log.child({ subgraph: subgraphName });
213+
if (transportContext) {
214+
let log = executionRequest.context?.request
215+
? loggerForRequest(
216+
transportContext.log,
217+
executionRequest.context.request,
218+
)
219+
: transportContext.log;
220+
if (subgraphName) {
221+
log = log.child({ subgraph: subgraphName });
222+
}
223+
// overwrite the log in the transport context because now it contains more details
224+
transportContext.log = log;
225+
log.debug('Initializing executor');
214226
}
215-
// overwrite the log in the transport context because now it contains more details
216-
transportContext.log = log;
217-
log.debug('Initializing executor');
218227
// Lazy executor that loads transport executor on demand
219228
executor = function lazyExecutor(subgraphExecReq: ExecutionRequest) {
220229
return handleMaybePromise(
@@ -273,7 +282,7 @@ export interface WrapExecuteWithHooksOptions {
273282
subgraphName: string;
274283
transportEntryMap?: Record<string, TransportEntry>;
275284
getSubgraphSchema: (subgraphName: string) => GraphQLSchema;
276-
transportContext: TransportContext;
285+
transportContext?: TransportContext;
277286
instrumentation: () => Instrumentation | undefined;
278287
}
279288

@@ -305,7 +314,9 @@ export function wrapExecutorWithHooks({
305314
baseExecutionRequest.rootValue = {
306315
executionRequest: baseExecutionRequest,
307316
};
308-
const log = transportContext.log.child({ subgraph: subgraphName });
317+
const log =
318+
transportContext?.log.child({ subgraph: subgraphName }) ||
319+
new Logger({ attrs: { subgraph: subgraphName } });
309320
if (onSubgraphExecuteHooks.length === 0) {
310321
return baseExecutor(baseExecutionRequest);
311322
}
@@ -331,7 +342,7 @@ export function wrapExecutorWithHooks({
331342
},
332343
executor,
333344
setExecutor(newExecutor) {
334-
log?.debug('executor has been updated');
345+
log.debug('executor has been updated');
335346
executor = newExecutor;
336347
},
337348
log: log,
@@ -354,7 +365,7 @@ export function wrapExecutorWithHooks({
354365
onSubgraphExecuteDoneHook({
355366
result: currentResult,
356367
setResult(newResult: ExecutionResult) {
357-
log?.debug('overriding result with: ', newResult);
368+
log.debug('overriding result with: ', newResult);
358369
currentResult = newResult;
359370
},
360371
}),
@@ -394,7 +405,7 @@ export function wrapExecutorWithHooks({
394405
onNext({
395406
result: currentResult,
396407
setResult: (res) => {
397-
log?.debug('overriding result with: ', res);
408+
log.debug('overriding result with: ', res);
398409

399410
currentResult = res;
400411
},

packages/fusion-runtime/tests/polling.test.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,10 @@ describe('Polling', () => {
6161

6262
const disposeFn = vi.fn();
6363

64-
const log = new Logger({ level: false });
6564
await using manager = new UnifiedGraphManager({
6665
getUnifiedGraph: unifiedGraphFetcher,
6766
pollingInterval: pollingInterval,
6867
batch: false,
69-
transportContext: { log, logger: LegacyLogger.from(log) },
7068
transports() {
7169
return {
7270
getSubgraphExecutor() {
@@ -201,12 +199,10 @@ describe('Polling', () => {
201199
},
202200
]);
203201
});
204-
const log = new Logger({ level: false });
205202
await using manager = new UnifiedGraphManager({
206203
getUnifiedGraph: unifiedGraphFetcher,
207204
pollingInterval: pollingInterval,
208205
batch: false,
209-
transportContext: { log, logger: LegacyLogger.from(log) },
210206
transports() {
211207
return {
212208
getSubgraphExecutor() {
@@ -299,11 +295,9 @@ describe('Polling', () => {
299295
]);
300296
});
301297
let disposeFn = vi.fn();
302-
const log = new Logger({ level: false });
303298
await using executor = getExecutorForUnifiedGraph({
304299
getUnifiedGraph: unifiedGraphFetcher,
305300
pollingInterval: 1000,
306-
transportContext: { log, logger: LegacyLogger.from(log) },
307301
transports() {
308302
return {
309303
getSubgraphExecutor() {

packages/fusion-runtime/tests/utils.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,8 @@ import {
2222
} from '../src/unifiedGraphManager';
2323

2424
export function composeAndGetPublicSchema(subgraphs: SubgraphConfig[]) {
25-
const log = new Logger({ level: false });
2625
const manager = new UnifiedGraphManager({
2726
getUnifiedGraph: () => getUnifiedGraphGracefully(subgraphs),
28-
transportContext: {
29-
log,
30-
logger: LegacyLogger.from(log),
31-
},
3227
transports() {
3328
return {
3429
getSubgraphExecutor({ subgraphName }) {

0 commit comments

Comments
 (0)