Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions app/lib/services/wals/local_wal_sync.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class LocalWalSyncImpl implements LocalWalSync {
Timer? _chunkingTimer;
Timer? _flushingTimer;

bool _isFlushing = false;

IWalSyncListener listener;

int _framesPerSecond = 100;
Expand Down Expand Up @@ -199,39 +201,52 @@ class LocalWalSyncImpl implements LocalWalSync {
}

Future _flush() async {
Logger.debug("_flushing");
for (var i = 0; i < _wals.length; i++) {
final wal = _wals[i];

if (wal.storage == WalStorage.mem) {
String? filePath = await Wal.getFilePath(wal.getFileName());
if (filePath == null) {
throw Exception('Flushing to storage failed. Cannot get file path.');
}
if (_isFlushing) {
Logger.debug("LocalWalSync: Flush already in progress, skipping");
return;
}
_isFlushing = true;

List<int> data = [];
for (int i = 0; i < wal.data.length; i++) {
var frame = wal.data[i].sublist(3);
try {
Logger.debug("_flushing");
for (var i = 0; i < _wals.length; i++) {
final wal = _wals[i];

if (wal.storage == WalStorage.mem) {
String? filePath = await Wal.getFilePath(wal.getFileName());
if (filePath == null) {
throw Exception('Flushing to storage failed. Cannot get file path.');
}

final byteFrame = ByteData(frame.length);
for (int i = 0; i < frame.length; i++) {
byteFrame.setUint8(i, frame[i]);
List<int> data = [];
for (int i = 0; i < wal.data.length; i++) {
var frame = wal.data[i].sublist(3);

final byteFrame = ByteData(frame.length);
for (int i = 0; i < frame.length; i++) {
byteFrame.setUint8(i, frame[i]);
}
data.addAll(Uint32List.fromList([frame.length]).buffer.asUint8List());
data.addAll(byteFrame.buffer.asUint8List());
}
data.addAll(Uint32List.fromList([frame.length]).buffer.asUint8List());
data.addAll(byteFrame.buffer.asUint8List());
}
final file = File(filePath);
await file.writeAsBytes(data);
wal.filePath = wal.getFileName();
wal.storage = WalStorage.disk;
final file = File(filePath);
await file.writeAsBytes(data);
wal.filePath = wal.getFileName();
wal.storage = WalStorage.disk;

Logger.debug("_flush file ${wal.filePath}");
Logger.debug("_flush file ${wal.filePath}");

_wals[i] = wal;
_wals[i] = wal;
}
}
}

await _saveWalsToFile();
await _saveWalsToFile();
} catch (e) {
Logger.debug("LocalWalSync: Error during flush: $e");
rethrow;
} finally {
_isFlushing = false;
}
}

Future<void> _saveWalsToFile() async {
Expand Down
55 changes: 38 additions & 17 deletions app/lib/utils/wal_file_manager.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';

Expand All @@ -18,6 +19,7 @@ class WalFileManager {

static File? _walFile;
static File? _walBackupFile;
static Future<void> _lastSaveFuture = Future.value();

static Future<void> init() async {
final directory =
Expand Down Expand Up @@ -53,28 +55,47 @@ class WalFileManager {
}

static Future<bool> saveWals(List<Wal> wals) async {
if (_walFile == null) {
await init();
}
final previousFuture = _lastSaveFuture;
final completer = Completer<void>();
_lastSaveFuture = completer.future;

if (_walFile == null) {
Logger.debug('WAL file is null, cannot save');
return false;
}
await previousFuture.catchError((_) {});

await _createBackup();
try {
if (_walFile == null) {
await init();
}

final jsonData = {
'version': 1,
'timestamp': DateTime.now().millisecondsSinceEpoch,
'wals': wals.map((wal) => wal.toJson()).toList(),
};
if (_walFile == null) {
Logger.debug('WAL file is null, cannot save');
return false;
}

final jsonString = jsonEncode(jsonData);
await _walFile!.writeAsString(jsonString);
if (!_walFile!.parent.existsSync()) {
try {
await _walFile!.parent.create(recursive: true);
} catch (e) {
Logger.debug('Failed to create WAL directory: $e');
return false;
}
}

await _createBackup();

final jsonData = {
'version': 1,
'timestamp': DateTime.now().millisecondsSinceEpoch,
'wals': wals.map((wal) => wal.toJson()).toList(),
};

Logger.debug('Successfully saved ${wals.length} WALs to file');
return true;
final jsonString = jsonEncode(jsonData);
await _walFile!.writeAsString(jsonString);

Logger.debug('Successfully saved ${wals.length} WALs to file');
return true;
} finally {
completer.complete();
}
}

static Future<void> _createBackup() async {
Expand Down