# ProcessMonitor
<span class="source-link">[[Source]](src/process/process_monitor.md#L9)</span>

Fork+execs / creates a child process and monitors it. Notifies a client about
STDOUT / STDERR events.


```pony
actor tag ProcessMonitor
```

## Constructors

### create
<span class="source-link">[[Source]](src/process/process_monitor.md#L35)</span>


Create infrastructure to communicate with a forked child process and
register the asio events. Fork child process and notify our user about
incoming data via the notifier.


```pony
new tag create(
  auth: (AmbientAuth val | StartProcessAuth val),
  backpressure_auth: (AmbientAuth val | ApplyReleaseBackpressureAuth val),
  notifier: ProcessNotify iso,
  filepath: FilePath val,
  args: Array[String val] val,
  vars: Array[String val] val,
  wdir: (FilePath val | None val) = reference,
  process_poll_interval: U64 val = call)
: ProcessMonitor tag^
```
#### Parameters

*   auth: ([AmbientAuth](builtin-AmbientAuth.md) val | [StartProcessAuth](process-StartProcessAuth.md) val)
*   backpressure_auth: ([AmbientAuth](builtin-AmbientAuth.md) val | [ApplyReleaseBackpressureAuth](backpressure-ApplyReleaseBackpressureAuth.md) val)
*   notifier: [ProcessNotify](process-ProcessNotify.md) iso
*   filepath: [FilePath](files-FilePath.md) val
*   args: [Array](builtin-Array.md)\[[String](builtin-String.md) val\] val
*   vars: [Array](builtin-Array.md)\[[String](builtin-String.md) val\] val
*   wdir: ([FilePath](files-FilePath.md) val | [None](builtin-None.md) val) = reference
*   process_poll_interval: [U64](builtin-U64.md) val = call

#### Returns

* [ProcessMonitor](process-ProcessMonitor.md) tag^

---

## Public Behaviours

### print
<span class="source-link">[[Source]](src/process/process_monitor.md#L150)</span>


Print some bytes and append a newline.


```pony
be print(
  data: (String val | Array[U8 val] val))
```
#### Parameters

*   data: ([String](builtin-String.md) val | [Array](builtin-Array.md)\[[U8](builtin-U8.md) val\] val)

---

### write
<span class="source-link">[[Source]](src/process/process_monitor.md#L159)</span>


Write to STDIN of the child process.


```pony
be write(
  data: (String val | Array[U8 val] val))
```
#### Parameters

*   data: ([String](builtin-String.md) val | [Array](builtin-Array.md)\[[U8](builtin-U8.md) val\] val)

---

### printv
<span class="source-link">[[Source]](src/process/process_monitor.md#L167)</span>


Print an iterable collection of ByteSeqs.


```pony
be printv(
  data: ByteSeqIter val)
```
#### Parameters

*   data: [ByteSeqIter](builtin-ByteSeqIter.md) val

---

### writev
<span class="source-link">[[Source]](src/process/process_monitor.md#L176)</span>


Write an iterable collection of ByteSeqs.


```pony
be writev(
  data: ByteSeqIter val)
```
#### Parameters

*   data: [ByteSeqIter](builtin-ByteSeqIter.md) val

---

### done_writing
<span class="source-link">[[Source]](src/process/process_monitor.md#L184)</span>


Set the _done_writing flag to true. If _pending is empty we can close the
_stdin pipe.


```pony
be done_writing()
```

---

### dispose
<span class="source-link">[[Source]](src/process/process_monitor.md#L195)</span>


Terminate child and close down everything.


```pony
be dispose()
```

---

### timer_notify
<span class="source-link">[[Source]](src/process/process_monitor.md#L243)</span>


Windows IO polling timer has fired


```pony
be timer_notify()
```

---

## Public Functions

### expect
<span class="source-link">[[Source]](src/process/process_monitor.md#L203)</span>


A `stdout` call on the notifier must contain exactly `qty` bytes. If
`qty` is zero, the call can contain any amount of data.


```pony
fun ref expect(
  qty: USize val = 0)
: None val
```
#### Parameters

*   qty: [USize](builtin-USize.md) val = 0

#### Returns

* [None](builtin-None.md) val

---

## Private Behaviours

### _event_notify
<span class="source-link">[[Source]](src/process/process_monitor.md#L211)</span>


Handle the incoming Asio event from one of the pipes.


```pony
be _event_notify(
  event: Pointer[AsioEvent val] tag,
  flags: U32 val,
  arg: U32 val)
```
#### Parameters

*   event: [Pointer](builtin-Pointer.md)\[[AsioEvent](builtin-AsioEvent.md) val\] tag
*   flags: [U32](builtin-U32.md) val
*   arg: [U32](builtin-U32.md) val

---

### _wait_for_child
<span class="source-link">[[Source]](src/process/process_monitor.md#L264)</span>


```pony
be _wait_for_child()
```

---

### _read_again
<span class="source-link">[[Source]](src/process/process_monitor.md#L394)</span>


Resume reading on file descriptor.


```pony
be _read_again(
  near_fd: U32 val)
```
#### Parameters

*   near_fd: [U32](builtin-U32.md) val

---

## Private Functions

### _close
<span class="source-link">[[Source]](src/process/process_monitor.md#L252)</span>


Close all pipes and wait for the child process to exit.


```pony
fun ref _close()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

### _ensure_timers
<span class="source-link">[[Source]](src/process/process_monitor.md#L286)</span>


```pony
fun ref _ensure_timers()
: Timers tag
```

#### Returns

* [Timers](time-Timers.md) tag

---

### _dispose_timers
<span class="source-link">[[Source]](src/process/process_monitor.md#L295)</span>


```pony
fun ref _dispose_timers()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

### _setup_windows_timers
<span class="source-link">[[Source]](src/process/process_monitor.md#L302)</span>


```pony
fun ref _setup_windows_timers()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

### _try_shutdown
<span class="source-link">[[Source]](src/process/process_monitor.md#L314)</span>


If neither stdout nor stderr are open we close down and exit.


```pony
fun ref _try_shutdown()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

### _pending_reads
<span class="source-link">[[Source]](src/process/process_monitor.md#L325)</span>


Read from stdout or stderr while data is available. If we read 4 kb of
data, send ourself a resume message and stop reading, to avoid starving
other actors.
It's safe to use the same buffer for stdout and stderr because of
causal messaging. Events get processed one _after_ another.


```pony
fun ref _pending_reads(
  pipe: _Pipe ref)
: None val
```
#### Parameters

*   pipe: [_Pipe](process-_Pipe.md) ref

#### Returns

* [None](builtin-None.md) val

---

### _read_buf_size
<span class="source-link">[[Source]](src/process/process_monitor.md#L387)</span>


```pony
fun ref _read_buf_size()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

### _write_final
<span class="source-link">[[Source]](src/process/process_monitor.md#L403)</span>


Write as much as possible to the pipe if it is open and there are no
pending writes. Save everything unwritten into _pending and apply
backpressure.


```pony
fun ref _write_final(
  data: (String val | Array[U8 val] val))
: None val
```
#### Parameters

*   data: ([String](builtin-String.md) val | [Array](builtin-Array.md)\[[U8](builtin-U8.md) val\] val)

#### Returns

* [None](builtin-None.md) val

---

### _pending_writes
<span class="source-link">[[Source]](src/process/process_monitor.md#L434)</span>


Send any pending data. If any data can't be sent, keep it in _pending.
Once _pending is non-empty, direct writes will get queued there,
and they can only be written here. If the _done_writing flag is set, close
the pipe once we've processed pending writes.


```pony
fun ref _pending_writes()
: None val
```

#### Returns

* [None](builtin-None.md) val

---

