lockRelease method

Future<void> lockRelease(
  1. String name, {
  2. required Function perform,
  3. bool shouldSetState = true,
  4. void onError(
    1. Object error,
    2. StackTrace stackTrace
    )?,
})

The lockRelease method will call the function provided in perform and then block the function from being called again until it has finished.

E.g. lockRelease('update', perform: () async { await handleSomething(); });

Use isLocked to check if the function is still locked. E.g. isLocked('update') // true/false

The lock is released however perform ends. An Exception it throws goes to onError once the lock is released, so the caller can react (show what went wrong, undo an optimistic change, try again); without onError it is logged with its stack trace. Anything else (an Error, i.e. a bug) is rethrown once the lock is released.

E.g. lockRelease('save', perform: () async { await api

Implementation

Future<void> lockRelease(
  String name, {
  required Function perform,
  bool shouldSetState = true,
  void Function(Object error, StackTrace stackTrace)? onError,
}) async {
  if (isLocked(name) == true) {
    return;
  }
  _updateLockState(shouldSetState: shouldSetState, name: name, value: true);

  Exception? failure;
  StackTrace? failureStackTrace;
  try {
    await perform();
  } on Exception catch (e, stackTrace) {
    failure = e;
    failureStackTrace = stackTrace;
  } finally {
    _updateLockState(
      shouldSetState: shouldSetState,
      name: name,
      value: false,
    );
  }

  if (failure == null) return;
  if (onError != null) {
    onError(failure, failureStackTrace ?? StackTrace.current);
    return;
  }
  NyLogger.error(failure, stackTrace: failureStackTrace);
}