Skip to content

Commit

Permalink
v1 Release Preparation (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaffaKetchup authored Oct 7, 2023
1 parent fde39d9 commit dac6a1d
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 58 deletions.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
custom: "https://docs.fleaflet.dev/supporters#support-us"
51 changes: 51 additions & 0 deletions .github/workflows/branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: "Branch & Fork CI/CD"
on:
push:
branches:
- '!master'
pull_request:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true

jobs:
score-package:
name: "Score Package"
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Run Dart Package Analyser
uses: axel-op/dart-package-analyzer@master
id: analysis
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Check Package Scores
env:
TOTAL: ${{ steps.analysis.outputs.total }}
TOTAL_MAX: ${{ steps.analysis.outputs.total_max }}
run: |
if (( $TOTAL < $TOTAL_MAX - 10 ))
then
echo Package score less than available score. Improve the score!
exit 1
fi
analyse-code:
name: "Analyse Code"
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Flutter Environment
uses: subosito/flutter-action@v2
with:
channel: "stable"
- name: Get All Dependencies
run: flutter pub get
- name: Check Formatting
run: dart format --output=none --set-exit-if-changed .
- name: Check Lints
run: dart analyze --fatal-infos --fatal-warnings
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# flutter_map_cancellable_tile_provider

Plugin for [flutter_map](https://github.com/fleaflet/flutter_map) that provides a `TileProvider` with the capability to cancel unnecessary HTTP requests (on the web)
Plugin for [flutter_map](https://github.com/fleaflet/flutter_map) that provides a `TileProvider` that fetches tiles from the network, with the capability to cancel unnecessary HTTP tile requests

- Reduce tile loading durations
Tiles that are removed/pruned before they are fully loaded do not need to complete (down)loading, and therefore do not need to complete the HTTP interaction. Cancelling these unnecessary tile requests early could:

- Reduce tile loading durations (particularly on the web)
- Reduce users' (cellular) data and cache space consumption
- Reduce costly tile requests to tile servers*
- Reduce (cellular) data consumption
- Improve performance by reducing CPU and IO work

---
This provider uses '[dio](https://pub.dev/packages/dio)', which supports aborting unnecessary HTTP requests in-flight, after they have already been sent.

Unlike `NetworkTileProvider`, this uses '[dio](https://pub.dev/packages/dio)' to support cancelling/aborting unnecessary HTTP requests in-flight. Tiles that are removed/pruned before they are fully loaded do not need to complete loading, and therefore do not need to complete the request/download. This results in the tiles currently in the map's camera/viewport being loaded faster, as the tiles loaded whilst panning, zooming, or rotating are pruned, freeing up HTTP connections. It may also result in a reduction of costs, as there are less full tile requests to your tile server, but this will depend on their backend configuration and how quickly the tile is pruned.
Although HTTP request abortion is supported on all platforms, it is especially useful on the web - and therefore recommended for web apps. This is because the web platform has a limited number of simulatous HTTP requests, and so closing the requests allows new requests to be made for new tiles.
On other platforms, the other benefits may still occur, but may not be as visible as on the web.

Note that these advantages only occur on the web, as only the web supports the abortion of HTTP requests. On other platforms, this acts equivalent to `NetworkTileProvider`, except using 'dio' instead of 'http'.
Once HTTP request abortion is [added to Dart's 'native' 'http' package (which already has a PR opened)](https://github.com/dart-lang/http/issues/424), `NetworkTileProvider` will be updated to take advantage of it, replacing and deprecating this provider. This tile provider is currently a separate package and not the default due to the reliance on the additional Dio dependency.
108 changes: 60 additions & 48 deletions lib/flutter_map_cancellable_tile_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,44 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_map/flutter_map.dart';

/// [TileProvider] to fetch tiles from the network, with cancellation support
/// [TileProvider] that fetches tiles from the network, with the capability to
/// cancel unnecessary HTTP tile requests
///
/// Unlike [NetworkTileProvider], this uses [Dio] and supports
/// cancelling/aborting unnecessary HTTP requests in-flight. Tiles that are
/// removed/pruned before they are fully loaded do not need to complete loading,
/// and therefore do not need to complete the request/download. This results in
/// the tiles currently in the map's camera/viewport being loaded faster, as the
/// tiles loaded whilst panning, zooming, or rotating are pruned, freeing up HTTP
/// connections. It may also result in a reduction of costs, as there are less
/// full tile requests to your tile server, but this will depend on their backend
/// configuration and how quickly the tile is pruned.
/// {@template tp-desc}
///
/// Note that these advantages only occur on the web, as only the web supports
/// the abortion of HTTP requests. On other platforms, this acts equivalent to
/// [NetworkTileProvider], except using 'package:dio' instead of 'package:http'.
/// Tiles that are removed/pruned before they are fully loaded do not need to
/// complete (down)loading, and therefore do not need to complete the HTTP
/// interaction. Cancelling these unnecessary tile requests early could:
///
/// - Reduce tile loading durations (particularly on the web)
/// - Reduce users' (cellular) data and cache space consumption
/// - Reduce costly tile requests to tile servers*
/// - Improve performance by reducing CPU and IO work
///
/// This provider uses '[dio](https://pub.dev/packages/dio)', which supports
/// aborting unnecessary HTTP requests in-flight, after they have already been
/// sent.
///
/// Although HTTP request abortion is supported on all platforms, it is
/// especially useful on the web - and therefore recommended for web apps. This
/// is because the web platform has a limited number of simulatous HTTP requests,
/// and so closing the requests allows new requests to be made for new tiles.
/// On other platforms, the other benefits may still occur, but may not be as
/// visible as on the web.
///
/// Once HTTP request abortion is [added to Dart's 'native' 'http' package (which already has a PR opened)](https://github.com/dart-lang/http/issues/424), `NetworkTileProvider` will be updated to take advantage of it, replacing and deprecating this provider. This tile provider is currently a seperate package and not the default due to the reliance on the additional Dio dependency.
///
/// ---
///
/// On the web, the 'User-Agent' header cannot be changed as specified in
/// [TileLayer.tileProvider]'s documentation, due to a Dart/browser limitation.
/// {@endtemplate}
class CancellableNetworkTileProvider extends TileProvider {
/// Create a [TileProvider] to fetch tiles from the network, with cancellation
/// support
///
/// Unlike [NetworkTileProvider], this uses [Dio] and supports
/// cancelling/aborting unnecessary HTTP requests in-flight. Tiles that are
/// removed/pruned before they are fully loaded do not need to complete
/// loading, and therefore do not need to complete the request/download. This
/// results in the tiles currently in the map's camera/viewport being loaded
/// faster, as the tiles loaded whilst panning, zooming, or rotating are
/// pruned, freeing up HTTP connections. It may also result in a reduction of
/// costs, as there are less full tile requests to your tile server, but this
/// will depend on their backend configuration and how quickly the tile is
/// pruned.
///
/// Note that these advantages only occur on the web, as only the web supports
/// the abortion of HTTP requests. On other platforms, this acts equivalent to
/// [NetworkTileProvider], except using 'package:dio' instead of
/// 'package:http'.
/// Create a [CancellableNetworkTileProvider] to fetch tiles from the network,
/// with cancellation support
///
/// On the web, the 'User-Agent' header cannot be changed as specified in
/// [TileLayer.tileProvider]'s documentation, due to a Dart/browser limitation.
CancellableNetworkTileProvider({
super.headers,
}) : _dio = Dio();
/// {@macro tp-desc}
CancellableNetworkTileProvider({super.headers}) : _dio = Dio();

final Dio _dio;
// ignore: use_late_for_private_fields_and_variables
Expand Down Expand Up @@ -125,17 +120,27 @@ class _CNTPImageProvider extends ImageProvider<_CNTPImageProvider> {
final cancelToken = CancelToken();
unawaited(cancelLoading.then((_) => cancelToken.cancel()));

final Uint8List bytes;
try {
final response = await tileProvider._dio.get<Uint8List>(
useFallback ? fallbackUrl! : url,
cancelToken: cancelToken,
options: Options(
headers: tileProvider.headers,
responseType: ResponseType.bytes,
final codec = decode(
await ImmutableBuffer.fromUint8List(
(await tileProvider._dio.get<Uint8List>(
useFallback ? fallbackUrl! : url,
cancelToken: cancelToken,
options: Options(
headers: tileProvider.headers,
responseType: ResponseType.bytes,
),
))
.data!,
),
);
bytes = response.data!;
).catchError((e) {
// ignore: only_throw_errors
if (useFallback || fallbackUrl == null) throw e as Object;
return _loadAsync(key, chunkEvents, decode, useFallback: true);
});

cancelLoading.ignore();
return codec;
} on DioException catch (err) {
if (CancelToken.isCancel(err)) {
return decode(
Expand All @@ -147,11 +152,18 @@ class _CNTPImageProvider extends ImageProvider<_CNTPImageProvider> {
if (useFallback || fallbackUrl == null) rethrow;
return _loadAsync(key, chunkEvents, decode, useFallback: true);
} catch (_) {
// This redundancy necessary, do not remove
if (useFallback || fallbackUrl == null) rethrow;
return _loadAsync(key, chunkEvents, decode, useFallback: true);
}

cancelLoading.ignore();
return decode(await ImmutableBuffer.fromUint8List(bytes));
}

@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is _CNTPImageProvider && fallbackUrl == null && url == other.url);

@override
int get hashCode =>
Object.hashAll([url, if (fallbackUrl != null) fallbackUrl]);
}
11 changes: 7 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: flutter_map_cancellable_tile_provider
description: Plugin for flutter_map that provides a `TileProvider` with the capability to cancel unnecessary HTTP requests
version: 1.0.0-preview
description: Plugin for flutter_map that provides a `TileProvider` with the capability to cancel unnecessary HTTP tile requests
version: 1.0.0

homepage: https://github.com/fleaflet/flutter_map
repository: https://github.com/fleaflet/flutter_map_cancellable_tile_provider
issue_tracker: https://github.com/fleaflet/flutter_map/issues
documentation: https://docs.fleaflet.dev

funding:
- https://docs.fleaflet.dev/supporters#support-us

topics:
- flutter-map
- map
Expand All @@ -24,7 +27,7 @@ environment:
flutter: ">=3.10.0"

dependencies:
dio: ^5.3.2
dio: ^5.3.3
flutter:
sdk: flutter
flutter_map: ^6.0.0-dev.3
flutter_map: ^6.0.0

0 comments on commit dac6a1d

Please sign in to comment.