lesnitsky / flutter_localstorage

📦 LocalStorage for Flutter
MIT License
301 stars 60 forks source link

"FileSystemException: lock failed" on subsequent setItem() #62

Closed tcd93 closed 3 years ago

tcd93 commented 3 years ago

Version: 3.0.6, Platform: Windows

.setItem() method fails on 2nd call ``` FileSystemException: lock failed, path = 'C:\Users\tcd93\Documents/test' (OS Error: The process cannot access the file because another process has locked a portion of the file. , errno = 33) dart:io _RandomAccessFile.lock DirUtils.flush package:localstorage/…/directory/io.dart:47 LocalStorage._flush package:localstorage/localstorage.dart:102 LocalStorage.setItem package:localstorage/localstorage.dart:85 ===== asynchronous gap =========================== ```

Code:

import 'package:flutter_test/flutter_test.dart';
import 'package:localstorage/localstorage.dart';

void main() {
  LocalStorage storage;
  setUpAll(() => storage = new LocalStorage('test'));
  tearDownAll(() => storage.dispose());
  test('LocalStorage', () async {
    await storage.ready;
    await storage.setItem('test_key', '{"1": "one", "2": "two", "3": "three"}');
    await storage.setItem('test_key', '{"4": "four"}'); // fails
  });
}

Looks like it is caused by a missing _file.unlock here: https://github.com/lesnitsky/flutter_localstorage/blob/6f4447ea65c8479032ed04c36bef5340bdf67f53/lib/src/directory/io.dart#L44-L52

Not reproducible on real device / emulator

nohli commented 3 years ago

Can you please try adding WidgetsFlutterBinding.ensureInitialized(); as first line in main()?

tcd93 commented 3 years ago

@nohli same error, I think this is related to Dart

When I added await _file.unlock(); after line 51 in https://github.com/lesnitsky/flutter_localstorage/issues/62#issue-789817328 the error is gone, looks like this is the fix

tcd93 commented 3 years ago

Here's the doc for RandomAccessFile

NOTE file locking does have slight differences in behavior across platforms:

On Linux and OS X this uses advisory locks, which have the surprising semantics that all locks associated with a given file are removed when any file descriptor for that file is closed by the process. Note that this does not actually lock the file for access. Also note that advisory locks are on a process level. This means that several isolates in the same process can obtain an exclusive lock on the same file.

On Windows the regions used for lock and unlock needs to match. If that is not the case unlocking will result in the OS error "The segment is already unlocked".

I digged a little bit more, fcntl is used in Android & Linux whereas LockFileEx is used in Windows

So that explains why this can't be reproduced on mobile, because second _file.lock(); does nothing

Ali-Fadaei commented 3 years ago

@nohli same error, I think this is related to Dart

When I added await _file.unlock(); after line 51 in #62 (comment) the error is gone, looks like this is the fix

thank to solution! 🙏🏻. but if issue solved with this why don't update repo and close this after 25 days?