blob: 4a7681b6bbe9ac4a908c3525def3af44c316e899 [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. 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:convert';
import 'package:file/file.dart';
import 'package:intl/intl.dart';
import 'codecs.dart';
import 'common.dart';
import 'events.dart';
import 'recording.dart';
/// A mutable live recording.
class MutableRecording implements LiveRecording {
/// Creates a new `MutableRecording` that will serialize its data to the
/// specified [destination].
final List<LiveInvocationEvent<dynamic>> _events =
bool _flushing = false;
final Directory destination;
List<LiveInvocationEvent<dynamic>> get events =>
new List<LiveInvocationEvent<dynamic>>.unmodifiable(_events);
Future<Null> flush({Duration pendingResultTimeout}) async {
if (_flushing) {
throw new StateError('Recording is already flushing');
_flushing = true;
try {
Iterable<Future<Null>> futures =<dynamic> event) => event.done);
Future<List<Null>> results = Future.wait<Null>(futures);
if (pendingResultTimeout != null) {
results = results.timeout(pendingResultTimeout, onTimeout: () {});
await results;
Directory dir = destination;
String json = new JsonEncoder.withIndent(' ').convert(encode(_events));
String filename = dir.fileSystem.path.join(dir.path, kManifestName);
await dir.fileSystem.file(filename).writeAsString(json, flush: true);
} finally {
_flushing = false;
/// Returns a new file for use with this recording.
/// The file name will combine the specified [name] with [newUid] to ensure
/// that its name is unique among all recording files.
/// It is up to the caller to create the file - it will not exist in the
/// file system when it is returned from this method.
File newFile(String name) {
String basename = '${new NumberFormat('000').format(newUid())}.$name';
String dirname = destination.path;
String path = destination.fileSystem.path.join(dirname, basename);
return destination.fileSystem.file(path);
/// Adds the specified [event] to this recording.
void add(LiveInvocationEvent<dynamic> event) => _events.add(event);