Skip to content

Commit

Permalink
fix(*): Fix ref used after dispose and stream used after closed
Browse files Browse the repository at this point in the history
  • Loading branch information
realth000 committed Dec 5, 2023
1 parent cdd0f5e commit 8fe10ab
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
31 changes: 19 additions & 12 deletions lib/models/cookie_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,27 @@ import 'package:tsdm_client/utils/debug.dart';
/// username), what we can do is save these cookies as cache in memory.
/// And it's cookieProvider's work to save them to database.
class CookieData implements Storage {
CookieData(this.cookieStreamSink) : _username = null;
CookieData(this.cookieStreamController) : _username = null;

CookieData.withUsername({
required String username,
required Map<String, String> cookie,
required this.cookieStreamSink,
required this.cookieStreamController,
}) : _username = username,
_cookieMap = cookie;

CookieData.withData({
required String username,
required Map<String, String> cookie,
required this.cookieStreamSink,
required this.cookieStreamController,
}) : _username = username,
_cookieMap = cookie;

/// Stream to send cookie event.
final StreamSink<UserCookieEvent> cookieStreamSink;
/// Stream of [UserCookieEvent] to receive all cookie events happened in
/// [CookieData].
///
/// Handle events and sync cookie to database.
StreamController<UserCookieEvent>? cookieStreamController;

final String? _username;

Expand Down Expand Up @@ -66,10 +69,12 @@ class CookieData implements Storage {
return false;
}

cookieStreamSink.add(UserCookieEvent.update(
username: _username!,
cookie: _cookieMap,
));
if (cookieStreamController != null && cookieStreamController!.isClosed) {
cookieStreamController?.sink.add(UserCookieEvent.update(
username: _username!,
cookie: _cookieMap,
));
}
return true;
}

Expand All @@ -87,9 +92,11 @@ class CookieData implements Storage {
}

debug('CookieData $hashCode: delete cookie: $_username');
cookieStreamSink.add(UserCookieEvent.delete(
username: _username!,
));
if (cookieStreamController != null && !cookieStreamController!.isClosed) {
cookieStreamController?.sink.add(UserCookieEvent.delete(
username: _username!,
));
}
return true;
}

Expand Down
38 changes: 14 additions & 24 deletions lib/providers/cookie_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,15 @@ part '../generated/providers/cookie_provider.g.dart';
class Cookie extends _$Cookie {
String? _username;

/// Stream of [UserCookieEvent] to receive all cookie events happened in
/// [CookieData].
///
/// Handle events and sync cookie to database.
StreamController<UserCookieEvent>? _cookieStream;

// To make linter happy: Bypass "unclosed instance of 'Sink'" warning
// TODO: Find a proper time to close stream when instance disposing.
void _() {
_cookieStream?.close();
}

@override
CookieData build({String? username}) {
if (_cookieStream == null) {
_cookieStream = StreamController<UserCookieEvent>();
_cookieStream!.stream.listen((event) async {
await _handleCookieEvent(event);
});
}
// ignore: close_sinks
final streamController = StreamController<UserCookieEvent>();
streamController.stream.listen((event) async {
await _handleCookieEvent(event);
});

ref.onDispose(streamController.close);

// Specified user override.
if (username != null) {
Expand All @@ -70,17 +59,18 @@ class Cookie extends _$Cookie {
return CookieData.withUsername(
username: username,
cookie: cookie,
cookieStreamSink: _cookieStream!.sink,
cookieStreamController: streamController,
);
}

return _buildCookieDataFromLoginUser();
return _buildCookieDataFromLoginUser(streamController);
}

CookieData _buildCookieDataFromLoginUser() {
CookieData _buildCookieDataFromLoginUser(
StreamController<UserCookieEvent> streamController) {
final username = ref.watch(appSettingsProvider).loginUsername;
if (username.isEmpty) {
return CookieData(_cookieStream!.sink);
return CookieData(streamController);
}

_username = username;
Expand All @@ -91,13 +81,13 @@ class Cookie extends _$Cookie {
debug(
'failed to init cookie: current login user username=$username not found in database',
);
return CookieData(_cookieStream!.sink);
return CookieData(streamController);
}

return CookieData.withData(
username: _username!,
cookie: Map.castFrom(databaseCookie.cookie),
cookieStreamSink: _cookieStream!.sink,
cookieStreamController: streamController,
);
}

Expand Down

0 comments on commit 8fe10ab

Please sign in to comment.