EsAsyncZoneSpec
Description
A parameter object with custom zone function handlers for EsAsyncZone>>fork.
A zone specification is a parameter object passed to EsAsyncZone>>fork and any underlying fork handler custom implementations. The individual handlers, if set to a non-nil value, will be the implementation of the corresponding <EsAsyncZone> methods for a forked zone created using this zone specification.
Handlers have the same signature as the same-named methods on <EsAsyncZone>, but receive three additional arguments:
  1. The zone the handlers are attached to (the "self" zone). This is the zone created by EsAsyncZone>>fork where the
handler is passed as part of the zone delegation.
  1. A <EsAsyncZoneDelegate> to the parent zone.
  2. The "current" zone at the time the request was made. The self zone is always a parent zone of the current zone.
Handlers can either stop propagating the request (by simply not calling the parent handler), or forward to the parent zone, potentially modifying the arguments on the way.
Instance State
  • onRun: <Block | DirectedMessage>
  • onRegisterCallback: <Block | DirectedMessage>
  • onErrorCallback: <Block | DirectedMessage>
  • onScheduleTask: <Block | DirectedMessage>
  • onFork: <Block | DirectedMessage>
  • onHandleUncaughtError: <Block | DirectedMessage>
Class Methods
<details> from:
<pre><code> Creates a specification from @aZoneSpec.
The created zone specification has the handlers of @aZoneSpec.
After this, use setters on the instance side to plug in additional handlers
or override the handlers from @aZoneSpec.

Arguments:
aZoneSpec - <EsAsyncZoneSpec>
Answers:
<EsAsyncZoneSpec>
</code></pre> </details>
<details> new
<pre><code> Creates a default specification. Use setters on the instance side to plug in handlers. These will be used to override zone handlers when a
specification is used to fork a zone.
Answers:
<EsAsyncZoneSpec>
</code></pre> </details>
Instance Methods
<details> onErrorCallback
<pre><code> A custom EsAsyncZone>>errorCallback:stackTrace: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onErrorCallback:
<pre><code> The type of a custom EsAsyncZone>>errorCallback:stackTrace: implementation handler.
Signature:
<EsAsyncError|nil> errorCallbackHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
Object error,
EsAsyncStackTrace stackTrace)

Example: Intercept errors and overrides it.
```smalltalk
[(EsFuture error: 'error') catch: [:e | Transcript show: e]] asyncZoned: (
EsAsyncZoneSpec new onErrorCallback: [:selfZone :parent :zone :error :stackTrace |
parent errorCallback: error stackTrace: stackTrace zone: zone.
EsAsyncError error: ('override %1' bindWith: error asString) stackTrace: stackTrace])
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The `error` and `stackTrace` are the error and stack trace passed
to EsAsyncZone>>errorCallback:stackTrace: of `zone`.

The callable should return either `nil` if it doesn't want
to replace the original error and stack trace,
or an <EsAsyncError> containg a replacement error and stack trace
which will be used to replace the originals.

Arguments:
errorCallbackHandler - <Block | DirectedMessage>
</code></pre> </details>
<details> onFork
<pre><code> A custom EsAsyncZone>>fork: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onFork:
<pre><code> The type of a custom EsAsyncZone>>fork: implementation handler.
Signature:
EsAsyncZone forkHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
<EsAsyncZoneSpec|nil> specification,
<KeyedCollection|nil> zoneValues)

Example:
```smalltalk
[EsAsyncZone current fork] asyncZoned: (
EsAsyncZoneSpec new onFork: [:selfZone :parent :zone :specification :values | | newZone |
Transcript show: 'About to fork'.
newZone := parent fork: specification values: values zone: zone.
Transcript show: 'Finished fork'.
newZone])
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The handler should create a new zone with `zone` as its
immediate parent zone.

The `specification` and `zoneValues` are the ones which were
passed to EsAsyncZone>>fork: of `zone`. They specify the custom zone
handlers and zone variables that the new zone should have.

The custom handler can change the specification or zone
values before calling `parent fork:values:zone:`,
but it has to call the `parent`'s EsAsyncZoneDelegate>>fork:values:zone: in order
to create a valid <EsAsyncZone> object.

Arguments:
forkHandler - <Block | DirectedMessage>
</code></pre> </details>
<details> onHandleUncaughtError
<pre><code> A custom EsAsyncZone>>handleUncaughtError:stackTrace: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onHandleUncaughtError:
<pre><code> The type of a custom EsAsyncZone>>handleUncaughtError:stackTrace: implementation handler.
Signature:
void handleUncaughtErrorHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
Object error,
EsAsyncStackTrace stackTrace)

Example:
```smalltalk
[EsFuture error: 'oh no'] asyncZoned: (
EsAsyncZoneSpec new onHandleUncaughtError: [:selfZone :parent :zone :error :stackTrace |
Transcript show: error asString.
parent handleUncaughtError: error stackTrace: stackTrace zone: zone])
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The `error` and `stackTrace` are the error and stack trace that
was uncaught in `zone`.

Arguments:
handleUncaughtErrorHandler - <Block | DirectedMessage>
</code></pre> </details>
<details> onRegisterCallback
<pre><code> A custom EsAsyncZone>>registerCallback: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onRegisterCallback:
<pre><code> The type of a custom EsAsyncZone>>registerCallback: implementation handler.
Signature:
registerCallbackHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
<DirectedMessage|Block> f())

Example:
```smalltalk
[(EsFuture error: 'oh no') catch: [Transcript show: 'caught error']] asyncZoned: (
EsAsyncZoneSpec new onRegisterCallback: [:selfZone :parent :zone :f |
[
Transcript show: 'First say hi'; cr.
f value]])
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The callable `f` is the evaluatable code which was passed to the
EsAsyncZone>>registerCallback: of `zone`. 'f' can take a variable
number of arguments to include 0 arguments

The handler should return either the callable `f`
or another callable replacing `f`,
typically by wrapping `f` in another callable
which does something extra before and after invoking `f`.

Arguments:
registerCallbackHandler - <Block | DirectedMessage>
</code></pre> </details>
<details> onRun
<pre><code> A custom EsAsyncZone>>run: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onRun:
<pre><code> The type of a custom EsAsyncZone>>run: implementation handler.
Signature:
runHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
<DirectedMessage|Block> f(),
Array args
)

Example:
```smalltalk
| i |
i := 0.
[
EsAsyncZone current run: [3].
EsAsyncZone current run: [3]]
asyncZoned: (
EsAsyncZoneSpec new onRun: [:selfZone :parent :zone :f :args |
i := i + 1.
parent run: f withArguments: args zone: zone]).
i inspect
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The callable `f` is the evaluatable code which was passed to the
EsAsyncZone>>run: of `zone`.

The default behavior of EsAsyncZone>>run is
to call `f` in the current zone, `zone`.
A custom handler can do things before, after or instead of
calling `f`.

Arguments:
runHandler - <Block | DirectedMessage>
</code></pre> </details>
<details> onScheduleTask
<pre><code> A custom EsAsyncZone>>scheduleTask: implementation for a new zone. See setter for details.
Answers:
<DirectedMessage | Block>
</code></pre> </details>
<details> onScheduleTask:
<pre><code> The type of a custom EsAsyncZone>>scheduleTask: implementation handler.
Signature:
scheduleTaskHandler(
EsAsyncZone self,
EsAsyncZoneDelegate parent,
EsAyncZone zone,
f())

Example: Schedule all tasks to run on the UI process
```smalltalk
[EsFuture on: [5 inspect]] asyncZoned: (
EsAsyncZoneSpec new onScheduleTask: [:selfZone :parent :zone :f |
parent scheduleTask: [CwAppContext default asyncExecFirstInUI: f] zone: zone]).
```

Receives the <EsAsyncZone> that the handler was registered on as `self`,
a delegate forwarding to the handlers of `self`'s parent zone as `parent`,
and the current zone where the error was uncaught as `zone`,
which will have `self` as a parent zone.

The function `f` is the callable which was
passed to EsAsyncZone>>scheduleTask: of `zone`.

The custom handler can choose to replace the function `f`
with one that does something before, after or instead of calling `f`,
and then call `parent scheduleTask: zone with: replacement`.
or it can implement its own task scheduling queue, which typically
still depends on `parent scheduleTask:with:` to as a way to get started.

Arguments:
scheduleTaskHandler - <Block | DirectedMessage>
</code></pre> </details>
Last modified date: 04/21/2022