Skip to content

Commit

Permalink
feat(graphql): make timeout configurable in query options (#1475)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndelanou authored Dec 28, 2024
1 parent 3628544 commit b88fa9f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 3 deletions.
5 changes: 5 additions & 0 deletions packages/graphql/lib/src/core/_base_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ abstract class BaseOptions<TParsed extends Object?> {
ErrorPolicy? errorPolicy,
CacheRereadPolicy? cacheRereadPolicy,
this.optimisticResult,
this.queryRequestTimeout,
}) : policies = Policies(
fetch: fetchPolicy,
error: errorPolicy,
Expand Down Expand Up @@ -60,6 +61,9 @@ abstract class BaseOptions<TParsed extends Object?> {

final ResultParserFn<TParsed> parserFn;

/// Override default query timeout
final Duration? queryRequestTimeout;

// TODO consider inverting this relationship
/// Resolve these options into a request
Request get asRequest => Request(
Expand All @@ -80,6 +84,7 @@ abstract class BaseOptions<TParsed extends Object?> {
policies,
context,
parserFn,
queryRequestTimeout,
];

OperationType get type {
Expand Down
4 changes: 4 additions & 0 deletions packages/graphql/lib/src/core/mutation_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class MutationOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
this.update,
this.onError,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
}) : super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
Expand All @@ -40,6 +41,7 @@ class MutationOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
context: context,
optimisticResult: optimisticResult,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

final OnMutationCompleted? onCompleted;
Expand Down Expand Up @@ -68,6 +70,7 @@ class MutationOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
update: update,
onError: onError,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

WatchQueryOptions<TParsed> asWatchQueryOptions() =>
Expand All @@ -81,6 +84,7 @@ class MutationOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
fetchResults: false,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
}

Expand Down
13 changes: 11 additions & 2 deletions packages/graphql/lib/src/core/query_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class QueryManager {
final bool alwaysRebroadcast;

/// The timeout for resolving a query
final Duration requestTimeout;
final Duration? requestTimeout;

QueryScheduler? scheduler;
static final _oneOffOpId = '0';
Expand Down Expand Up @@ -260,7 +260,16 @@ class QueryManager {

try {
// execute the request through the provided link(s)
response = await link.request(request).timeout(this.requestTimeout).first;
Stream<Response> responseStream = link.request(request);

// Resolve the request timeout by first checking the options of this specific request,
// then the manager level requestTimeout.
// Only apply the timeout if it is non-null.
final timeout = options.queryRequestTimeout ?? this.requestTimeout;
if (timeout case final Duration timeout) {
responseStream = responseStream.timeout(timeout);
}
response = await responseStream.first;

queryResult = mapFetchResultToQueryResult(
response,
Expand Down
22 changes: 22 additions & 0 deletions packages/graphql/lib/src/core/query_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
this.pollInterval,
Context? context,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
this.onComplete,
this.onError,
}) : super(
Expand All @@ -39,6 +40,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
context: context,
optimisticResult: optimisticResult,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

final OnQueryComplete? onComplete;
Expand Down Expand Up @@ -68,6 +70,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
Duration? pollInterval,
Context? context,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
OnQueryComplete? onComplete,
OnQueryError? onError,
}) =>
Expand All @@ -82,6 +85,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
pollInterval: pollInterval ?? this.pollInterval,
context: context ?? this.context,
parserFn: parserFn ?? this.parserFn,
queryRequestTimeout: queryRequestTimeout ?? this.queryRequestTimeout,
onComplete: onComplete ?? this.onComplete,
onError: onError ?? this.onError,
);
Expand All @@ -95,6 +99,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
fetchPolicy: FetchPolicy.noCache,
errorPolicy: errorPolicy,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
context: context,
variables: {
...variables,
Expand All @@ -115,6 +120,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
context: context,
optimisticResult: optimisticResult,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

QueryOptions<TParsed> copyWithPolicies(Policies policies) => QueryOptions(
Expand All @@ -128,6 +134,7 @@ class QueryOptions<TParsed extends Object?> extends BaseOptions<TParsed> {
pollInterval: pollInterval,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
}

Expand All @@ -144,6 +151,7 @@ class SubscriptionOptions<TParsed extends Object?>
Object? optimisticResult,
Context? context,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
}) : super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
Expand All @@ -154,6 +162,7 @@ class SubscriptionOptions<TParsed extends Object?>
context: context,
optimisticResult: optimisticResult,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
SubscriptionOptions<TParsed> copyWithPolicies(Policies policies) =>
SubscriptionOptions(
Expand All @@ -166,6 +175,7 @@ class SubscriptionOptions<TParsed extends Object?>
optimisticResult: optimisticResult,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
}

Expand All @@ -185,6 +195,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
bool? eagerlyFetchResults,
Context? context,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
}) : eagerlyFetchResults = eagerlyFetchResults ?? fetchResults,
super(
document: document,
Expand All @@ -197,6 +208,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
context: context,
optimisticResult: optimisticResult,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

/// Whether or not to fetch results every time a new listener is added.
Expand Down Expand Up @@ -237,6 +249,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
bool? eagerlyFetchResults,
Context? context,
ResultParserFn<TParsed>? parserFn,
Duration? queryRequestTimeout,
}) =>
WatchQueryOptions<TParsed>(
document: document ?? this.document,
Expand All @@ -253,6 +266,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException ?? this.carryForwardDataOnException,
context: context ?? this.context,
parserFn: parserFn ?? this.parserFn,
queryRequestTimeout: queryRequestTimeout ?? this.queryRequestTimeout,
);

WatchQueryOptions<TParsed> copyWithFetchPolicy(
Expand All @@ -272,6 +286,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException: carryForwardDataOnException,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
WatchQueryOptions<TParsed> copyWithPolicies(
Policies policies,
Expand All @@ -290,6 +305,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException: carryForwardDataOnException,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

WatchQueryOptions<TParsed> copyWithPollInterval(Duration? pollInterval) =>
Expand All @@ -307,6 +323,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException: carryForwardDataOnException,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

WatchQueryOptions<TParsed> copyWithVariables(
Expand All @@ -325,6 +342,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException: carryForwardDataOnException,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);

WatchQueryOptions<TParsed> copyWithOptimisticResult(
Expand All @@ -343,6 +361,7 @@ class WatchQueryOptions<TParsed extends Object?> extends QueryOptions<TParsed> {
carryForwardDataOnException: carryForwardDataOnException,
context: context,
parserFn: parserFn,
queryRequestTimeout: queryRequestTimeout,
);
}

Expand All @@ -358,6 +377,7 @@ class FetchMoreOptions {
this.document,
this.variables = const {},
required this.updateQuery,
Duration? queryRequestTimeout,
});

/// Automatically merge the results of [updateQuery] into `previousResultData`.
Expand All @@ -369,11 +389,13 @@ class FetchMoreOptions {
DocumentNode? document,
Map<String, dynamic> variables = const {},
required UpdateQuery updateQuery,
Duration? queryRequestTimeout,
}) =>
FetchMoreOptions(
document: document,
variables: variables,
updateQuery: partialUpdater(updateQuery),
queryRequestTimeout: queryRequestTimeout,
);

final DocumentNode? document;
Expand Down
2 changes: 1 addition & 1 deletion packages/graphql/lib/src/graphql_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class GraphQLClient implements GraphQLDataProxy {
bool alwaysRebroadcast = false,
DeepEqualsFn? deepEquals,
bool deduplicatePollers = false,
Duration queryRequestTimeout = const Duration(seconds: 5),
Duration? queryRequestTimeout = const Duration(seconds: 5),
}) : defaultPolicies = defaultPolicies ?? DefaultPolicies(),
queryManager = QueryManager(
link: link,
Expand Down

0 comments on commit b88fa9f

Please sign in to comment.