Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(graphql) make timeout configurable in query options #1475

Merged
merged 1 commit into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading