-
Notifications
You must be signed in to change notification settings - Fork 249
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(api): Subscription Reconnection #2074
Changes from 49 commits
110672a
66d99bf
2ff8e51
f4211af
5608b59
985b045
7b6ce8e
cb6fbdb
a1e8d9d
3ac59f4
4009458
48c9582
bef7f19
fcc53a0
32178ca
8bc47dd
826d470
b786902
2abff51
80aa0d5
7fc1cea
ff85ce2
9ddea6b
8e52487
4941901
e780b22
daaff32
d2bafc9
d6f6405
d6d6019
5829de8
f6c1c1b
2e05c6f
3cae1e9
e411b69
ea0950e
76d9907
50f878e
e721775
85c4227
e6230c5
12de4f0
5431552
c926e66
426e0fa
51e8917
4aab1e1
b8677e9
3264fc7
d3896e7
6b5bf50
dc00c44
b1f162b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
# | ||
|
||
list(APPEND FLUTTER_PLUGIN_LIST | ||
connectivity_plus_windows | ||
) | ||
|
||
list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-18/"/> | ||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> | ||
<classpathentry kind="output" path="bin/default"/> | ||
</classpath> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
# | ||
|
||
list(APPEND FLUTTER_PLUGIN_LIST | ||
connectivity_plus_windows | ||
) | ||
|
||
list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,10 @@ class AmplifyHubImpl extends AmplifyHub { | |
Future.wait<void>([ | ||
for (final stream in _availableStreams.values) stream.close(), | ||
]).ignore(); | ||
Future.wait<void>([ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed this from before, but what does this block do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No worries, this was just added. @dnys1 helped debug this one. It cleans up hub event subscriptions on cancel, an issue I was seeing in testing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cool, thanks for info. Might be worth a small comment here to explain. |
||
for (final subs in _subscriptions.values) | ||
for (final sub in subs) sub.cancel() | ||
]).ignore(); | ||
_availableStreams.clear(); | ||
_subscriptions.clear(); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import 'package:retry/retry.dart'; | ||
|
||
/// Configuration options for GraphQL Subscriptions and their WebSockets. | ||
class GraphQLSubscriptionOptions { | ||
/// Configure the ping interval for AppSync polling for subscription connections. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Would it make sense to state the default here? I'm guessing customers will see these comments when seeing what options they can provide and when deciding to provide a value or not it helps to know what the default is. |
||
final Duration? pingInterval; | ||
|
||
/// Configure the exponential retry strategy options | ||
Equartey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// see: https://pub.dev/documentation/retry/latest/retry/RetryOptions-class.html | ||
final RetryOptions? retryOptions; | ||
|
||
const GraphQLSubscriptionOptions({this.pingInterval, this.retryOptions}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import 'package:amplify_core/amplify_core.dart'; | ||
|
||
class ApiHubEvent extends HubEvent<ApiHubEventPayload> { | ||
ApiHubEvent( | ||
super.eventName, { | ||
super.payload, | ||
}); | ||
} | ||
|
||
abstract class ApiHubEventPayload { | ||
const ApiHubEventPayload(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/* | ||
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import 'package:amplify_core/amplify_core.dart'; | ||
|
||
/// {@template amplify_common.hub.api_network_state} | ||
/// Network states for graphql subscriptions. | ||
/// {@endtemplate} | ||
enum NetworkState { | ||
/// {@macro amplify_common.hub.api_network_state_connected} | ||
connected, | ||
|
||
/// {@macro amplify_common.hub.api_network_state_disconnected} | ||
disconnected, | ||
|
||
/// {@macro amplify_common.hub.api_network_state_failed} | ||
failed; | ||
} | ||
|
||
/// {@template amplify_common.hub.api_intended_state} | ||
/// The intended network states for graphql subscriptions. | ||
/// {@endtemplate} | ||
enum IntendedState { | ||
/// {@macro amplify_common.hub.api_intended_state_connected} | ||
connected, | ||
|
||
/// {@macro amplify_common.hub.api_intended_state_disconnected} | ||
disconnected; | ||
} | ||
|
||
/// {@template amplify_common.hub.api_subscription_status} | ||
/// A consolidated subscription connection status determined by the network and | ||
/// intended states. | ||
/// {@endtemplate} | ||
enum SubscriptionStatus { | ||
/// {@macro amplify_common.hub.api_subscription_status_connected} | ||
connected, | ||
|
||
/// {@macro amplify_common.hub.api_subscription_status_disconnected} | ||
disconnected, | ||
|
||
/// {@macro amplify_common.hub.api_subscription_status_connected} | ||
connecting, | ||
|
||
/// {@macro amplify_common.hub.api_subscription_status_disconnected} | ||
pendingDisconnected, | ||
|
||
/// {@macro amplify_common.hub.api_subscription_status_failed} | ||
failed; | ||
} | ||
|
||
class SubscriptionDetails extends ApiHubEventPayload | ||
with | ||
AWSEquatable<SubscriptionDetails>, | ||
AWSSerializable<Map<String, Object?>>, | ||
AWSDebuggable { | ||
/// {@macro amplify_common.hub.api_network_state} | ||
final NetworkState networkState; | ||
|
||
/// {@macro amplify_common.hub.api_intended_state} | ||
final IntendedState intendedState; | ||
|
||
SubscriptionDetails(this.networkState, this.intendedState); | ||
|
||
@override | ||
List<Object?> get props => [intendedState, networkState]; | ||
|
||
@override | ||
Map<String, String> toJson() => { | ||
'networkState': networkState.name, | ||
'intendedState': intendedState.name, | ||
}; | ||
|
||
@override | ||
String get runtimeTypeName => 'SubscriptionDetails'; | ||
} | ||
|
||
class SubscriptionHubEvent extends ApiHubEvent | ||
Equartey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
with | ||
AWSEquatable<SubscriptionHubEvent>, | ||
AWSSerializable<Map<String, Object?>>, | ||
AWSDebuggable { | ||
final SubscriptionDetails details; | ||
|
||
static const String _name = 'SubscriptionHubEvent'; | ||
|
||
SubscriptionHubEvent._(this.details) : super(_name, payload: details); | ||
|
||
/// {@template amplify_common.hub.api_subscription_status} | ||
/// An overall status for GraphQL subscription connection, determined by the | ||
/// underlying details [networkState] & [intendedState] | ||
/// {@endtemplate} | ||
SubscriptionStatus get status { | ||
// Connection failed | ||
if (details.networkState == NetworkState.failed) { | ||
return SubscriptionStatus.failed; | ||
} | ||
// Connected with active subscriptions | ||
if (details.networkState == NetworkState.connected && | ||
details.intendedState == IntendedState.connected) { | ||
return SubscriptionStatus.connected; | ||
} | ||
// Disconnected with active subscriptions | ||
if (details.networkState == NetworkState.disconnected && | ||
details.intendedState == IntendedState.connected) { | ||
return SubscriptionStatus.connecting; | ||
} | ||
// Connected without active subscriptions | ||
if (details.networkState == NetworkState.connected && | ||
details.intendedState == IntendedState.disconnected) { | ||
return SubscriptionStatus.pendingDisconnected; | ||
} | ||
|
||
// disconnected without active subscriptions | ||
return SubscriptionStatus.disconnected; | ||
} | ||
|
||
/// {@template amplify_common.hub.api_subscription_connected} | ||
/// Emitted when a GraphQL subscription is connected. | ||
/// {@endtemplate} | ||
SubscriptionHubEvent.connected() | ||
: this._(SubscriptionDetails( | ||
NetworkState.connected, IntendedState.connected)); | ||
|
||
/// {@template amplify_common.hub.api_subscription_connected} | ||
/// Emitted when a GraphQL subscription is connecting/reconnecting. | ||
/// {@endtemplate} | ||
SubscriptionHubEvent.connecting() | ||
: this._(SubscriptionDetails( | ||
NetworkState.disconnected, IntendedState.connected)); | ||
|
||
/// {@template amplify_common.hub.api_subscription_disconnected} | ||
/// Emitted when a GraphQL subscription connection has disconnected. | ||
/// {@endtemplate} | ||
SubscriptionHubEvent.disconnected() | ||
: this._(SubscriptionDetails( | ||
NetworkState.disconnected, IntendedState.disconnected)); | ||
|
||
/// {@template amplify_common.hub.api_subscription_pending_disconnect} | ||
/// Emitted when a GraphQL subscription connection is pending disconnect, | ||
/// but should exist. | ||
/// {@endtemplate} | ||
SubscriptionHubEvent.pendingDisconnect() | ||
: this._(SubscriptionDetails( | ||
NetworkState.connected, IntendedState.disconnected)); | ||
|
||
/// {@template amplify_common.hub.api_subscription_failed} | ||
/// Emitted when a GraphQL subscription connection has failed. | ||
/// {@endtemplate} | ||
SubscriptionHubEvent.failed() | ||
: this._(SubscriptionDetails( | ||
NetworkState.failed, IntendedState.disconnected)); | ||
|
||
@override | ||
List<Object?> get props => [details, status]; | ||
|
||
@override | ||
String get runtimeTypeName => 'SubscriptionHubEvent'; | ||
|
||
@override | ||
Map<String, Object?> toJson() => <String, dynamic>{ | ||
'status': status.name, | ||
'details': details.toJson(), | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when I run
aft bs
I get similar file modifications inpackages/api/amplify_api/example/macos/Flutter/GeneratedPluginRegistrant.swift
. Should that be added as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I noticed some extra generated files didn't committed. Will include them next push 👍