You've already forked immich
mirror of
https://github.com/immich-app/immich.git
synced 2025-08-07 23:03:36 +02:00
feat: websocket background sync (#19888)
* feat: websocket background sync * batch websocket * pr feedback
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
@ -10,6 +11,7 @@ import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/models/server_info/server_version.model.dart';
|
||||
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/auth.provider.dart';
|
||||
import 'package:immich_mobile/providers/background_sync.provider.dart';
|
||||
import 'package:immich_mobile/providers/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
@ -106,6 +108,18 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
final Debouncer _debounce =
|
||||
Debouncer(interval: const Duration(milliseconds: 500));
|
||||
|
||||
final Debouncer _batchDebouncer = Debouncer(
|
||||
interval: const Duration(seconds: 5),
|
||||
maxWaitTime: const Duration(seconds: 10),
|
||||
);
|
||||
final List<dynamic> _batchedAssetUploadReady = [];
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_batchDebouncer.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// Connects websocket to server unless already connected
|
||||
void connect() {
|
||||
if (state.isConnected) return;
|
||||
@ -171,6 +185,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
socket.on('on_asset_stack_update', _handleServerUpdates);
|
||||
socket.on('on_asset_hidden', _handleOnAssetHidden);
|
||||
socket.on('on_new_release', _handleReleaseUpdates);
|
||||
socket.on('AssetUploadReadyV1', _handleSyncAssetUploadReady);
|
||||
} catch (e) {
|
||||
debugPrint("[WEBSOCKET] Catch Websocket Error - ${e.toString()}");
|
||||
}
|
||||
@ -180,6 +195,8 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
void disconnect() {
|
||||
debugPrint("Attempting to disconnect from websocket");
|
||||
|
||||
_batchedAssetUploadReady.clear();
|
||||
|
||||
var socket = state.socket?.disconnect();
|
||||
|
||||
if (socket?.disconnected == true) {
|
||||
@ -288,7 +305,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
}
|
||||
|
||||
void handlePendingChanges() async {
|
||||
Future<void> handlePendingChanges() async {
|
||||
await _handlePendingUploaded();
|
||||
await _handlePendingDeletes();
|
||||
await _handlingPendingHidden();
|
||||
@ -347,6 +364,29 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
.read(serverInfoProvider.notifier)
|
||||
.handleNewRelease(serverVersion, releaseVersion);
|
||||
}
|
||||
|
||||
void _handleSyncAssetUploadReady(dynamic data) {
|
||||
_batchedAssetUploadReady.add(data);
|
||||
_batchDebouncer.run(_processBatchedAssetUploadReady);
|
||||
}
|
||||
|
||||
void _processBatchedAssetUploadReady() {
|
||||
if (_batchedAssetUploadReady.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
unawaited(
|
||||
_ref
|
||||
.read(backgroundSyncProvider)
|
||||
.syncWebsocketBatch(_batchedAssetUploadReady.toList()),
|
||||
);
|
||||
} catch (error) {
|
||||
_log.severe("Error processing batched AssetUploadReadyV1 events: $error");
|
||||
}
|
||||
|
||||
_batchedAssetUploadReady.clear();
|
||||
}
|
||||
}
|
||||
|
||||
final websocketProvider =
|
||||
|
Reference in New Issue
Block a user