| 76 | } |
| 77 | |
| 78 | export class WatchDog implements IDisposable { |
| 79 | private readonly onEndEmitter = new EventEmitter<IStopMetadata>(); |
| 80 | private readonly cts = new CancellationTokenSource(); |
| 81 | private target?: WebSocketTransport; |
| 82 | private gracefulExit = false; |
| 83 | private targetAlive = false; |
| 84 | private readonly targetInfo: WatchdogTarget = { |
| 85 | targetId: this.info.ownId ?? createTargetId(), |
| 86 | processId: Number(this.info.pid) || 0, |
| 87 | type: this.info.waitForDebugger ? 'waitingForDebugger' : '', |
| 88 | title: this.info.scriptName, |
| 89 | url: 'file://' + this.info.scriptName, |
| 90 | openerId: this.info.openerId, |
| 91 | attached: true, |
| 92 | canAccessOpener: false, |
| 93 | processInspectorPort: Number(new URL(this.info.inspectorURL).port), |
| 94 | }; |
| 95 | |
| 96 | /** |
| 97 | * Gets whether the attached process is still running. |
| 98 | */ |
| 99 | public get isTargetAlive() { |
| 100 | return this.targetAlive; |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Event that fires when the watchdog stops. |
| 105 | */ |
| 106 | public readonly onEnd = this.onEndEmitter.event; |
| 107 | |
| 108 | /** |
| 109 | * Creates a watchdog and returns a promise that resolves once it's attached |
| 110 | * to the server. |
| 111 | */ |
| 112 | public static async attach(info: IWatchdogInfo) { |
| 113 | const pipe: net.Socket = await new Promise((resolve, reject) => { |
| 114 | const cnx: net.Socket = net.createConnection(info.ipcAddress, () => resolve(cnx)); |
| 115 | cnx.on('error', reject); |
| 116 | }); |
| 117 | |
| 118 | const server = new RawPipeTransport(Logger.null, pipe); |
| 119 | return new WatchDog(info, server); |
| 120 | } |
| 121 | |
| 122 | constructor(private readonly info: IWatchdogInfo, private readonly server: ITransport) { |
| 123 | this.listenToServer(); |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * Attaches listeners to server messages to start passing them to the target. |
| 128 | * Should be called once when the watchdog is created. |
| 129 | */ |
| 130 | private listenToServer() { |
| 131 | const { server, targetInfo } = this; |
| 132 | server.send(JSON.stringify({ method: 'Target.targetCreated', params: { targetInfo } })); |
| 133 | server.onMessage(async ([data]) => { |
| 134 | // Fast-path to check if we might need to parse it: |
| 135 | if ( |
nothing calls this directly
no test coverage detected