LCOV - code coverage report
Current view: top level - lib/src/database - zone_transaction_mixin.dart (source / functions) Hit Total Coverage
Test: merged.info Lines: 15 15 100.0 %
Date: 2024-09-04 20:26:16 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           2 :       return await action();
      27             :     }
      28             :     // if we are *not* in a transaction, time to wait for the lock!
      29          36 :     while (_transactionLock != null) {
      30           4 :       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 1.14