process_manager.dart 2.86 KB
Newer Older
1 2 3 4 5 6
// Copyright 2016 The Chromium 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';

7 8
import 'package:process/process.dart';
import 'package:process/record_replay.dart';
9

10
import 'common.dart';
11
import 'context.dart';
12
import 'file_system.dart';
13
import 'process.dart';
14

15
const String _kRecordingType = 'process';
16
const ProcessManager _kLocalProcessManager = const LocalProcessManager();
17

18
/// The active process manager.
19 20 21 22 23
ProcessManager get processManager {
  return context == null
      ? _kLocalProcessManager
      : context[ProcessManager];
}
24

25 26
/// Enables recording of process invocation activity to the specified base
/// recording [location].
27 28 29 30
///
/// This sets the [active process manager](processManager) to one that records
/// all process activity before delegating to a [LocalProcessManager].
///
31 32 33 34
/// Activity will be recorded in a subdirectory of [location] named `"process"`.
/// It is permissible for [location] to represent an existing non-empty
/// directory as long as there is no collision with the `"process"`
/// subdirectory.
35
void enableRecordingProcessManager(String location) {
36 37 38 39
  final ProcessManager originalProcessManager = processManager;
  final Directory dir = getRecordingSink(location, _kRecordingType);
  final ProcessManager delegate = const LocalProcessManager();
  final RecordingProcessManager manager = new RecordingProcessManager(delegate, dir);
40 41 42 43
  addShutdownHook(() async {
    await manager.flush(finishRunningProcesses: true);
    context.setVariable(ProcessManager, originalProcessManager);
  }, ShutdownStage.SERIALIZE_RECORDING);
44
  context.setVariable(ProcessManager, manager);
45
}
46

47
/// Enables process invocation replay mode.
48
///
49 50
/// This sets the [active process manager](processManager) to one that replays
/// process activity from a previously recorded set of invocations.
51
///
52 53
/// [location] must represent a directory to which process activity has been
/// recorded (i.e. the result of having been previously passed to
54
/// [enableRecordingProcessManager]), or a [ToolExit] will be thrown.
55
Future<Null> enableReplayProcessManager(String location) async {
56
  final Directory dir = getReplaySource(location, _kRecordingType);
57 58 59 60 61 62 63 64 65 66

  ProcessManager manager;
  try {
    manager = await ReplayProcessManager.create(dir,
      // TODO(tvolkert): Once https://github.com/flutter/flutter/issues/7166 is
      //     resolved, we can use the default `streamDelay`. In the
      //     meantime, native file I/O operations cause our `tail` process
      //     streams to flush before our protocol discovery is listening on
      //     them, causing us to timeout waiting for the observatory port.
      streamDelay: const Duration(milliseconds: 50),
67
    );
68 69
  } on ArgumentError catch (error) {
    throwToolExit('Invalid replay-from: $error');
70 71
  }

72
  context.setVariable(ProcessManager, manager);
73
}