mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-05-15 12:42:14 -04:00
messages work
This commit is contained in:
parent
43dbf26cc0
commit
634543910b
47 changed files with 2206 additions and 123 deletions
114
packages/mutex/example/example.dart
Normal file
114
packages/mutex/example/example.dart
Normal file
|
@ -0,0 +1,114 @@
|
|||
// Mutex example.
|
||||
//
|
||||
// This example demonstrates why a mutex is needed.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:mutex/mutex.dart';
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Random asynchronous delays to try and simulate race conditions.
|
||||
|
||||
const _maxDelay = 500; // milliseconds
|
||||
|
||||
final _random = Random();
|
||||
|
||||
Future<void> randomDelay() async {
|
||||
await Future<void>.delayed(
|
||||
Duration(milliseconds: _random.nextInt(_maxDelay)));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/// Account balance.
|
||||
///
|
||||
/// The classical example of a race condition is when a bank account is updated
|
||||
/// by different simultaneous operations.
|
||||
|
||||
int balance = 0;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/// Deposit without using mutex.
|
||||
|
||||
Future<void> unsafeUpdate(int id, int depositAmount) async {
|
||||
// Random delay before updating starts
|
||||
await randomDelay();
|
||||
|
||||
// Add the deposit to the balance. But this operation is not atomic if
|
||||
// there are asynchronous operations in it (as simulated by the randomDelay).
|
||||
|
||||
final oldBalance = balance;
|
||||
await randomDelay();
|
||||
balance = oldBalance + depositAmount;
|
||||
|
||||
print(' [$id] added $depositAmount to $oldBalance -> $balance');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/// Deposit using mutex.
|
||||
|
||||
Mutex m = Mutex();
|
||||
|
||||
Future<void> safeUpdate(int id, int depositAmount) async {
|
||||
// Random delay before updating starts
|
||||
await randomDelay();
|
||||
|
||||
// Acquire the mutex before running the critical section of code
|
||||
|
||||
await m.protect(() async {
|
||||
// critical section
|
||||
|
||||
// This is the same as the unsafe update. But since it is performed only
|
||||
// when the mutex is acquired, it is safe: no other safe update can happen
|
||||
// until this mutex is released.
|
||||
|
||||
final oldBalance = balance;
|
||||
await randomDelay();
|
||||
balance = oldBalance + depositAmount;
|
||||
|
||||
// end of critical section
|
||||
|
||||
print(' [$id] added $depositAmount to $oldBalance -> $balance');
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/// Make a series of deposits and see if the final balance is correct.
|
||||
|
||||
Future<void> makeDeposits({bool safe = true}) async {
|
||||
print(safe ? 'Using mutex:' : 'Not using mutex:');
|
||||
|
||||
const numberDeposits = 10;
|
||||
const amount = 10;
|
||||
|
||||
balance = 0;
|
||||
|
||||
// Create a set of operations, each attempting to deposit the same amount
|
||||
// into the account.
|
||||
|
||||
final operations = <Future<void>>[];
|
||||
for (var x = 0; x < numberDeposits; x++) {
|
||||
final f = (safe) ? safeUpdate(x, amount) : unsafeUpdate(x, amount);
|
||||
operations.add(f);
|
||||
}
|
||||
|
||||
// Wait for all the deposit operations to finish
|
||||
|
||||
await Future.wait<void>(operations);
|
||||
|
||||
// Check if all of the operations succeeded
|
||||
|
||||
final expected = numberDeposits * amount;
|
||||
if (balance != expected) {
|
||||
print('Error: deposits were lost (final balance $balance != $expected)');
|
||||
} else {
|
||||
print('Success: no deposits were lost');
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
void main() async {
|
||||
await makeDeposits(safe: false);
|
||||
print('');
|
||||
await makeDeposits(safe: true);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue