@@ -40,6 +40,7 @@ abstract class ContainerState with _$ContainerState {
4040class ContainerNotifier extends _$ContainerNotifier {
4141 var sudoCompleter = Completer <bool >();
4242 String ? _cachedPassword;
43+ var _refreshGeneration = 0 ;
4344
4445 @override
4546 ContainerState build (
@@ -70,6 +71,7 @@ class ContainerNotifier extends _$ContainerNotifier {
7071 }
7172
7273 Future <void > setType (ContainerType type) async {
74+ final refreshGeneration = ++ _refreshGeneration;
7375 state = state.copyWith (
7476 type: type,
7577 error: null ,
@@ -81,7 +83,11 @@ class ContainerNotifier extends _$ContainerNotifier {
8183 );
8284 Stores .container.setType (type, hostId);
8385 sudoCompleter = Completer <bool >();
84- await refresh ();
86+ await refresh (generation: refreshGeneration);
87+ }
88+
89+ bool _isStaleRefresh (int generation) {
90+ return generation != _refreshGeneration || ! ref.mounted;
8591 }
8692
8793 Future <void > _requiresSudo (
@@ -112,14 +118,17 @@ class ContainerNotifier extends _$ContainerNotifier {
112118 }
113119 }
114120
115- Future <void > refresh ({bool isAuto = false }) async {
121+ Future <void > refresh ({bool isAuto = false , int ? generation }) async {
116122 if (state.isBusy) return ;
123+ final refreshGeneration = generation ?? _refreshGeneration;
124+ final type = state.type;
117125 state = state.copyWith (isBusy: true );
118126
119127 final sudo = sudoCompleter;
120- if (! sudo.isCompleted) unawaited (_requiresSudo (sudo, state. type));
128+ if (! sudo.isCompleted) unawaited (_requiresSudo (sudo, type));
121129
122130 final needSudo = await sudo.future;
131+ if (_isStaleRefresh (refreshGeneration)) return ;
123132
124133 /// If sudo is required and auto refresh is enabled, skip the refresh.
125134 /// Or this will ask for pwd again and again.
@@ -131,6 +140,7 @@ class ContainerNotifier extends _$ContainerNotifier {
131140 String ? password;
132141 if (needSudo) {
133142 password = await _getSudoPassword ();
143+ if (_isStaleRefresh (refreshGeneration)) return ;
134144 if (password == null ) {
135145 state = state.copyWith (
136146 isBusy: false ,
@@ -147,7 +157,7 @@ class ContainerNotifier extends _$ContainerNotifier {
147157
148158 final cmd = _wrap (
149159 ContainerCmdType .execAll (
150- state. type,
160+ type,
151161 sudo: needSudo,
152162 includeStats: includeStats,
153163 password: password,
@@ -168,14 +178,15 @@ class ContainerNotifier extends _$ContainerNotifier {
168178 },
169179 );
170180 } else {
181+ if (_isStaleRefresh (refreshGeneration)) return ;
171182 state = state.copyWith (
172183 isBusy: false ,
173184 error: ContainerErr (type: ContainerErrType .noClient),
174185 );
175186 return ;
176187 }
177188
178- if (! ref.mounted ) return ;
189+ if (_isStaleRefresh (refreshGeneration) ) return ;
179190 state = state.copyWith (isBusy: false );
180191
181192 if (! context.mounted) return ;
@@ -254,13 +265,13 @@ class ContainerNotifier extends _$ContainerNotifier {
254265 final psRaw = ContainerCmdType .ps.find (segments);
255266 try {
256267 final lines = psRaw.split ('\n ' );
257- if (state. type == ContainerType .docker) {
268+ if (type == ContainerType .docker) {
258269 /// Due to the fetched data is not in json format, skip table header
259270 lines.removeWhere ((element) => element.contains ('CONTAINER ID' ));
260271 }
261272 lines.removeWhere ((element) => element.isEmpty);
262273 final items = lines
263- .map ((e) => ContainerPs .fromRaw (e, state. type))
274+ .map ((e) => ContainerPs .fromRaw (e, type))
264275 .toList ();
265276 state = state.copyWith (items: items);
266277 } catch (e, trace) {
@@ -279,13 +290,13 @@ class ContainerNotifier extends _$ContainerNotifier {
279290 List <ContainerImg > images;
280291 if (isEntireJson) {
281292 images = (json.decode (imageRaw) as List )
282- .map ((e) => ContainerImg .fromRawJson (json.encode (e), state. type))
293+ .map ((e) => ContainerImg .fromRawJson (json.encode (e), type))
283294 .toList ();
284295 } else {
285296 final lines = imageRaw.split ('\n ' );
286297 lines.removeWhere ((element) => element.isEmpty);
287298 images = lines
288- .map ((e) => ContainerImg .fromRawJson (e, state. type))
299+ .map ((e) => ContainerImg .fromRawJson (e, type))
289300 .toList ();
290301 }
291302 state = state.copyWith (images: images);
0 commit comments