## 4.12. Timeout

Timeout, the ability to execute an expression for at most a specified amount of time, is an essential ingredient of fault-tolerant and distributed programming. Orc accomplishes timeout using pruning and the `Rwait` site. The following program runs F for at most one second, publishing its result if available and the value `0` otherwise.

```Let( F | Rwait(1000) >> 0 )
```

### 4.12.1. Auction with timeout

In the auction example given previously, the auction may never complete if one of the bidders does not respond. We can add a timeout so that a bidder has at most 8 seconds to provide a bid:

```def auction([]) = 0
def auction(b:bs) =
val bid = b.ask() | Rwait(8000) >> 0
max(bid, auction(bs))
```

This version of the auction is guaranteed to complete within 8 seconds.

### 4.12.2. Detecting timeout

Sometimes, rather than just yielding a default value, we would like to determine whether an expression has timed out, and if so, perform some other computation. To detect the timeout, we pair the result of the original expression with `true` and the result of the timer with `false`. Thus, if the expression does time out, then we can distinguish that case using the boolean value.

Here, we run expression F with a time limit `t`. If it publishes within the time limit, we bind its result to `r` and execute G. Otherwise, we execute H.

```val (r, b) = (F, true) | (Rwait(t), false)
if b then G else H
```

Instead of using a boolean and conditional, we could use pattern matching:

```val s = Some(F) | Rwait(t) >> None()
s >Some(r)> G
| s >None()>  H
```

It is even possible to encapsulate timeout as a function.

```def timeout(x, t) = Let(Some(x) | Rwait(t) >> None())
```

`timeout(F, t)` waits `t` milliseconds for F to publish a value. If F publishes `v` within the time limit, `timeout` returns `Some(v)`. Otherwise, it returns `None()` when the time limit is reached.

#### Timeout streams

We can also apply timeout to streams. Let's define a modified version of the `repeat` function as follows:

```def repeatWithTimeout(f, t) =
timeout(f(), t)
>Some(x)>
(x | repeatWithTimeout(f, t))

```

We call `f()` as before, but apply a timeout of `t` to the call. If a value becomes available from `f` before the timeout, then the call to `timeout` publishes `Some(x)`, which we match, and then publish `x` and recursively wait for further values from the stream.

However, if no value is available from `f` within the timeout, the call to `timeout` publishes `None()`. Since `None()` does not match the pattern, the entire expression halts, indicating that the end of the stream has been reached.

It is also possible to achieve this behavior with the existing `repeat` function, simply by changing the function passed to `repeat`:

```def f'() = timeout(f(), t) >Some(x)> x
repeat(f')
```