blob: 2eb2699ed605a823ea462dda5fceacf4c815db9d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:collection';
import 'package:fidl_fuchsia_ledger/fidl.dart' as ledger;
import 'ledger_helpers.dart';
import 'sledge.dart';
import 'transaction.dart';
/// Holds a Modification and a Completer. The [completer] completes
/// when [modification] has been ran.
class _Task {
final Completer<bool> completer = new Completer<bool>();
final Modification modification;
_Task(this.modification);
}
/// A queue of modifications that gets ran in transactions.
class ModificationQueue {
Transaction _currentTransaction;
final Queue<_Task> _tasks = new ListQueue<_Task>();
final Sledge _sledge;
final LedgerObjectsFactory _ledgerObjectsFactory;
final ledger.PageProxy _pageProxy;
/// Default constructor.
ModificationQueue(this._sledge, this._ledgerObjectsFactory, this._pageProxy);
/// Appends [modification] to the queue of modifications.
///
/// Will run [modification] once the previously queued modification
/// has ran.
/// Returns true if [modification] was successfully ran.
Future<bool> queueModification(Modification modification) async {
// The last task from the queue.
_Task taskToAwait;
if (_tasks.isNotEmpty) {
taskToAwait = _tasks.last;
}
final task = new _Task(modification);
_tasks.add(task);
// If some task was in the queue, await its completion.
if (taskToAwait != null) {
await taskToAwait.completer.future;
}
assert(_tasks.first == task);
assert(_currentTransaction == null);
// Create a transaction from [modifications], run it, and await its end.
_currentTransaction =
new Transaction(_sledge, _pageProxy, _ledgerObjectsFactory);
try {
return await _currentTransaction.saveModification(modification);
} finally {
_currentTransaction = null;
_tasks.removeFirst();
task.completer.complete(true);
}
}
/// The inflight transaction, if any.
Transaction get currentTransaction => _currentTransaction;
}