0

I am creating a disk cache and I faced problem while running flutter tests cause by json.decode() but I found that the problem is that the same file is being read twice at the same time.

Here is the code for the disk cache class:

import 'dart:convert';
import 'dart:io';

import 'package:path_provider/path_provider.dart';
import 'package:the_chef/repositories/cache/base_cache.dart';

class DiskCache<V> extends BaseCache<List<String>, V> {
  String directoryPath;

  DiskCache({
    BaseCache<List<String>, V> other,
  }) {
    next = other;
  }

  Future<V> _get(List<String> path) async {
    print("get $path");
    var val;
    var file;

    file = await _exists(path);
    if (file != null) {
      print("start");
      var str = await file.readAsString();
      val = json.decode(str);
      print("end get $path");
      return val;
    }

    val ??= next?.get(path);

    if (val != null) {
      await _createFile(file);
      var bytes = json.encode(val);
      await file.writeAsString(bytes);
    }

    if(val == null) {
        print("notfound");
    }

    return val;
  }


  Future<V> get(List<String> path) async {
    var x = await _get(path);
    return x;
  }

  @override
  Future<void> set(List<String> path, V value) async {
    print("set $path");

    final file = await _createFileFromPath(path);

    var bytes = json.encode(value);
    await file.writeAsString(bytes);

    next?.set(path, value);
    print("end set $path");
  }

  @override
  Future<void> evict(List<String> path) async {
    print("evict $path");
    final file = await _localFile(path);

    if (await file.exists()) {
      await file.delete();
    } else {
      await file.delete(recursive: true);
    }

    await next?.evict(path);
  }

  Future<File> _exists(List<String> path) async {
    var file = await _localFile(path);
    return (await file.exists()) ? file : null;
  }

  Future<File> _localFile(List<String> filePath) async {
    final path = await _localPath();
    return File('$path/${filePath.join('/')}');
  }

  Future<String> _localPath() async {
    if (directoryPath != null) {
      return directoryPath;
    }

    directoryPath = (await getApplicationDocumentsDirectory()).path;
    return directoryPath;
  }

  Future<File> _createFileFromPath(List<String> path) async {
    var file = await _localFile(path);
    await _createFile(file);
    return file;
  }

  Future<void> _createFile(File file) async {
    file.createSync(recursive: true);
  }
}

It would be very great if you have any suggestion of how to improve the cache or have any other advices. Thanks in advance.

Mina Toma
  • 1
  • 1
  • please check this answers, this might help you https://stackoverflow.com/questions/42071051/dart-how-to-manage-concurrency-in-async-function – Vilsad P P Jun 15 '20 at 10:34
  • I understood that but I have a different problem and it's that the class deals with different files so locking the whole function will slow down the read operations. – Mina Toma Jun 15 '20 at 14:41

0 Answers0