Skip to content

Commit

Permalink
✨ add per-request timeout (#604)
Browse files Browse the repository at this point in the history
  • Loading branch information
techouse authored May 2, 2024
1 parent 4fe8ccf commit c558b3b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 1 deletion.
11 changes: 11 additions & 0 deletions chopper/lib/src/annotations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ sealed class Method {
/// The above code produces hxxp://path/to/script&foo=foo_var&bar=&baz=baz_var
final bool? includeNullQueryVars;

/// Set a timeout for the request
final Duration? timeout;

/// {@macro Method}
const Method(
this.method, {
Expand All @@ -244,6 +247,7 @@ sealed class Method {
this.listFormat,
@Deprecated('Use listFormat instead') this.useBrackets,
this.includeNullQueryVars,
this.timeout,
});
}

Expand All @@ -261,6 +265,7 @@ final class Get extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Get);
}

Expand All @@ -280,6 +285,7 @@ final class Post extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Post);
}

Expand All @@ -297,6 +303,7 @@ final class Delete extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Delete);
}

Expand All @@ -316,6 +323,7 @@ final class Put extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Put);
}

Expand All @@ -334,6 +342,7 @@ final class Patch extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Patch);
}

Expand All @@ -351,6 +360,7 @@ final class Head extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Head);
}

Expand All @@ -368,6 +378,7 @@ final class Options extends Method {
super.listFormat,
super.useBrackets,
super.includeNullQueryVars,
super.timeout,
}) : super(HttpMethod.Options);
}

Expand Down
39 changes: 39 additions & 0 deletions chopper/test/test_service.chopper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions chopper/test/test_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ abstract class HttpTestService extends ChopperService {
@Field() final List<int> positives, [
@Field() final String? signature,
]);

@Get(path: 'get_timeout', timeout: Duration(seconds: 42))
Future<Response<String>> getTimeoutTest();

@Get(path: 'get_timeout_zero', timeout: Duration(seconds: 0))
Future<Response<String>> getTimeoutTestZero();

@Get(path: 'get_timeout_neg', timeout: Duration(seconds: -1))
Future<Response<String>> getTimeoutTestNeg();
}

Request customConvertRequest(Request req) {
Expand Down
11 changes: 10 additions & 1 deletion chopper_generator/lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ final class ChopperGenerator

final bool? includeNullQueryVars = Utils.getIncludeNullQueryVars(method);

final Duration? timeout = Utils.getTimeout(method);

blocks.add(
declareFinal(Vars.request.toString(), type: refer('Request'))
.assign(
Expand Down Expand Up @@ -454,12 +456,19 @@ final class ChopperGenerator
]);
}

final returnStatement =
Expression returnStatement =
refer(Vars.client.toString()).property('send').call(
[refer(Vars.request.toString())],
namedArguments,
typeArguments,
);
if (timeout != null) {
returnStatement = returnStatement.property('timeout').call([
refer('Duration').constInstance([], {
'microseconds': literalNum(timeout.inMicroseconds),
}),
]);
}

if (isResponseObject) {
// Return the response object directly from chopper.send
Expand Down
15 changes: 15 additions & 0 deletions chopper_generator/lib/src/utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math' show max;

import 'package:analyzer/dart/element/element.dart';
import 'package:chopper_generator/src/extensions.dart';
import 'package:code_builder/code_builder.dart';
Expand Down Expand Up @@ -33,6 +35,19 @@ final class Utils {
static bool? getIncludeNullQueryVars(ConstantReader method) =>
method.peek('includeNullQueryVars')?.boolValue;

static Duration? getTimeout(ConstantReader method) {
final ConstantReader? timeout = method.peek('timeout');
if (timeout != null) {
final int? microseconds =
timeout.objectValue.getField('_duration')?.toIntValue();
if (microseconds != null) {
return Duration(microseconds: max(microseconds, 0));
}
}

return null;
}

/// All positional required params must support nullability
static Parameter buildRequiredPositionalParam(ParameterElement p) =>
Parameter(
Expand Down
39 changes: 39 additions & 0 deletions chopper_generator/test/test_service.chopper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions chopper_generator/test/test_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ abstract class HttpTestService extends ChopperService {
@Field('fool') final String foo,
@Tag() Object? t1,
);

@Get(path: 'get_timeout', timeout: Duration(seconds: 42))
Future<Response<String>> getTimeoutTest();

@Get(path: 'get_timeout_zero', timeout: Duration(seconds: 0))
Future<Response<String>> getTimeoutTestZero();

@Get(path: 'get_timeout_neg', timeout: Duration(seconds: -1))
Future<Response<String>> getTimeoutTestNeg();
}

Request customConvertRequest(Request req) {
Expand Down

0 comments on commit c558b3b

Please sign in to comment.