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

add option to use cancellation token in ChopperClient #645

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
128 changes: 0 additions & 128 deletions chopper/example/definition.chopper.dart

This file was deleted.

22 changes: 3 additions & 19 deletions chopper/example/definition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,12 @@ import 'package:chopper/chopper.dart';

part 'definition.chopper.dart';

@ChopperApi(baseUrl: '/resources')
@ChopperApi(baseUrl: '/')
abstract class MyService extends ChopperService {
static MyService create(ChopperClient client) => _$MyService(client);

@Get(path: '/{id}')
Future<Response> getResource(
@Path() String id,
);

@Get(path: '/', headers: {'foo': 'bar'})
Future<Response<Map>> getMapResource(
@Query() String id,
);

@Get(path: '/resources')
Future<Response<List<Map>>> getListResources();

@Post(path: '/')
Future<Response> postResourceUrlEncoded(
@Field('a') String toto,
@Field() String b,
);
@Get(path: '/abc')
Future<Response<Map>> getLongTimeTest();

@Post(path: '/multi')
@multipart
Expand Down
19 changes: 16 additions & 3 deletions chopper/example/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:chopper/chopper.dart';
import 'package:cancellation_token/cancellation_token.dart';

import 'definition.dart';

Future<void> main() async {
var token = CancellationToken();
final chopper = ChopperClient(
baseUrl: Uri.parse('http://localhost:8000'),
services: [
Expand All @@ -14,11 +16,22 @@ Future<void> main() async {

final myService = chopper.getService<MyService>();

final response = await myService.getMapResource('1');
print(response.body);

Future.delayed(Duration(seconds: 2), () {
token.cancel();
});

try {
final response = await myService.getMapResource('1');
print(response.body);
}
on CancelledException {
print('cancelled by user!');
}


final list = await myService.getListResources();
print(list.body);

chopper.dispose();
}
}
10 changes: 8 additions & 2 deletions chopper/example/tag.chopper.dart

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

31 changes: 24 additions & 7 deletions chopper/lib/src/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:chopper/src/converters.dart';
import 'package:chopper/src/interceptors/interceptor.dart';
import 'package:chopper/src/request.dart';
import 'package:chopper/src/response.dart';
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;
import 'package:meta/meta.dart';

/// ChopperClient is the main class of the Chopper API.
Expand Down Expand Up @@ -45,6 +45,8 @@ base class ChopperClient {

final bool _clientIsInternal;

http.CancellationToken? _cancellationToken;

/// Creates and configures a [ChopperClient].
///
/// The base URL of each request of the registered services can be defined
Expand Down Expand Up @@ -107,6 +109,7 @@ base class ChopperClient {
this.authenticator,
this.converter,
this.errorConverter,
http.CancellationToken? cancellationToken,
Iterable<ChopperService>? services,
}) : assert(
baseUrl == null || !baseUrl.hasQuery,
Expand All @@ -115,6 +118,7 @@ base class ChopperClient {
),
baseUrl = baseUrl ?? Uri(),
httpClient = client ?? http.Client(),
_cancellationToken = cancellationToken,
_clientIsInternal = client == null {
_services = <Type, ChopperService>{
for (final ChopperService service in services?.toSet() ?? [])
Expand Down Expand Up @@ -145,7 +149,6 @@ base class ChopperClient {
if (service == null) {
throw Exception("Service of type '$ServiceType' not found.");
}

return service as ServiceType;
}

Expand All @@ -172,12 +175,21 @@ base class ChopperClient {
requestCallback: _requestController.add,
);

final response = await call.execute<BodyType, InnerType>(
requestConverter,
responseConverter,
);
Response<BodyType> response;
try {
response = await call.execute<BodyType, InnerType>(
requestConverter,
responseConverter,
cancellationToken: _cancellationToken
);

_responseController.add(response);
_responseController.add(response);

}
on http.CancelledException {
_cancellationToken = http.CancellationToken();
rethrow;
}

return response;
}
Expand Down Expand Up @@ -321,6 +333,11 @@ base class ChopperClient {
),
);

/// Cancels any requests by the cancellation token (if exists)
void cancelRequests(){
_cancellationToken?.cancel();
}

/// Disposes this [ChopperClient] to clean up memory.
///
/// **Warning**: If a custom [http.Client] was provided while creating this `ChopperClient`,
Expand Down
4 changes: 3 additions & 1 deletion chopper/lib/src/chain/call.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:cancellation_token_http/http.dart' as http;
import 'package:chopper/src/annotations.dart';
import 'package:chopper/src/base.dart';
import 'package:chopper/src/chain/interceptor_chain.dart';
Expand Down Expand Up @@ -33,6 +34,7 @@ class Call {
Future<Response<BodyType>> execute<BodyType, InnerType>(
ConvertRequest? requestConverter,
ConvertResponse<BodyType>? responseConverter,
{http.CancellationToken? cancellationToken}
) async {
final interceptors = <Interceptor>[
RequestConverterInterceptor(client.converter, requestConverter),
Expand All @@ -45,7 +47,7 @@ class Call {
errorConverter: client.errorConverter,
responseConverter: responseConverter,
),
HttpCallInterceptor(client.httpClient),
HttpCallInterceptor(client.httpClient, cancellationToken: cancellationToken),
];

final interceptorChain = InterceptorChain<BodyType>(
Expand Down
2 changes: 1 addition & 1 deletion chopper/lib/src/interceptors/curl_interceptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:chopper/src/chain/chain.dart';
import 'package:chopper/src/interceptors/interceptor.dart';
import 'package:chopper/src/response.dart';
import 'package:chopper/src/utils.dart';
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;
import 'package:meta/meta.dart';

/// A [Interceptor] implementation that prints a curl request equivalent
Expand Down
9 changes: 6 additions & 3 deletions chopper/lib/src/interceptors/http_call_interceptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:chopper/src/chain/chain.dart';
import 'package:chopper/src/chopper_exception.dart';
import 'package:chopper/src/interceptors/internal_interceptor.dart';
import 'package:chopper/src/response.dart';
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;

import '../utils.dart';

Expand All @@ -13,7 +13,9 @@ import '../utils.dart';
/// {@endtemplate}
class HttpCallInterceptor implements InternalInterceptor {
/// {@macro HttpCallInterceptor}
const HttpCallInterceptor(this._httpClient);
const HttpCallInterceptor(this._httpClient, {this.cancellationToken});

final http.CancellationToken? cancellationToken;

/// HTTP client to be used for making the actual HTTP calls.
final http.Client _httpClient;
Expand All @@ -22,7 +24,8 @@ class HttpCallInterceptor implements InternalInterceptor {
FutureOr<Response<BodyType>> intercept<BodyType>(
Chain<BodyType> chain) async {
final finalRequest = await chain.request.toBaseRequest();
final streamRes = await _httpClient.send(finalRequest);
final streamRes = await _httpClient.send(
finalRequest, cancellationToken: cancellationToken);

if (isTypeOf<BodyType, Stream<List<int>>>()) {
return Response(streamRes, (streamRes.stream) as BodyType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:chopper/src/interceptors/interceptor.dart';
import 'package:chopper/src/request.dart';
import 'package:chopper/src/response.dart';
import 'package:chopper/src/utils.dart';
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;
import 'package:logging/logging.dart';
import 'package:meta/meta.dart';

Expand Down
2 changes: 1 addition & 1 deletion chopper/lib/src/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'dart:async' show Stream;
import 'package:chopper/src/extensions.dart';
import 'package:chopper/src/utils.dart';
import 'package:equatable/equatable.dart' show EquatableMixin;
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:qs_dart/qs_dart.dart' show ListFormat;

Expand Down
2 changes: 1 addition & 1 deletion chopper/lib/src/response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:typed_data';

import 'package:chopper/src/chopper_http_exception.dart';
import 'package:equatable/equatable.dart' show EquatableMixin;
import 'package:http/http.dart' as http;
import 'package:cancellation_token_http/http.dart' as http;
import 'package:meta/meta.dart';

/// {@template response}
Expand Down
2 changes: 1 addition & 1 deletion chopper/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ environment:

dependencies:
equatable: ^2.0.5
http: ^1.1.0
cancellation_token_http: ^2.1.0
logging: ^1.2.0
meta: ^1.9.1
qs_dart: ^1.2.4
Expand Down
Loading
Loading