LCOV - code coverage report
Current view: top level - lib/src/database - zone_transaction_mixin.dart (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 15 15
Test Date: 2025-01-14 13:39:53 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:async';
       2              : 
       3              : // we want transactions to lock, however NOT if transactoins are run inside of each other.
       4              : // to be able to do this, we use dart zones (https://dart.dev/articles/archive/zones).
       5              : // _transactionZones holds a set of all zones which are currently running a transaction.
       6              : // _transactionLock holds the lock.
       7              : mixin ZoneTransactionMixin {
       8              :   Completer<void>? _transactionLock;
       9              :   final _transactionZones = <Zone>{};
      10              : 
      11           36 :   Future<void> zoneTransaction(Future<void> Function() action) async {
      12              :     // first we try to determine if we are inside of a transaction currently
      13              :     var isInTransaction = false;
      14           36 :     Zone? zone = Zone.current;
      15              :     // for that we keep on iterating to the parent zone until there is either no zone anymore
      16              :     // or we have found a zone inside of _transactionZones.
      17              :     while (zone != null) {
      18           72 :       if (_transactionZones.contains(zone)) {
      19              :         isInTransaction = true;
      20              :         break;
      21              :       }
      22           36 :       zone = zone.parent;
      23              :     }
      24              :     // if we are inside a transaction....just run the action
      25              :     if (isInTransaction) {
      26            1 :       return await action();
      27              :     }
      28              :     // if we are *not* in a transaction, time to wait for the lock!
      29           36 :     while (_transactionLock != null) {
      30            6 :       await _transactionLock!.future;
      31              :     }
      32              :     // claim the lock
      33           36 :     final lock = Completer<void>();
      34           36 :     _transactionLock = lock;
      35              :     try {
      36              :       // run the action inside of a new zone
      37           72 :       return await runZoned(() async {
      38              :         try {
      39              :           // don't forget to add the new zone to _transactionZones!
      40          108 :           _transactionZones.add(Zone.current);
      41              : 
      42           36 :           await action();
      43              :           return;
      44              :         } finally {
      45              :           // aaaand remove the zone from _transactionZones again
      46          108 :           _transactionZones.remove(Zone.current);
      47              :         }
      48              :       });
      49              :     } finally {
      50              :       // aaaand finally release the lock
      51           36 :       _transactionLock = null;
      52           36 :       lock.complete();
      53              :     }
      54              :   }
      55              : }
        

Generated by: LCOV version 2.0-1