WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

Endpoint
Name:layer1.ForEach
Description:
Id:layer1.ForEach
Category:accessor
Identifier Syntax

layer1.ForEach is an accessor using Active URI syntax with the following base identifiers:

Base
active:forEach
active:forEachAsync
active:forEachTolerant
active:forEachAsyncTolerant

and the following arguments: (for more details on argument passing details see here)

ArgumentRulesTypingDescription
operand
Mandatory
Representation (java.lang.Object)java.lang.Iterable set of representations to process
do
Mandatory
Representation (java.lang.Object)declarative request defining operation on each representation
merge
Optional
Representation (java.lang.Object)optional declarative request to a process to merge the list of all representations/responses
timeout
Optional
Representation (java.lang.Object)optional timeout for async mode, must be transreptable to java.lang.Long
varargs [varargs] Any quantityRepresentation (java.lang.Object)Varargs allows an arbitrary number of additional unspecified arguments.
Request Verbs

The following verb is supported:

Verb
SOURCE
Response

The response representation of this accessor for SOURCE requests is unknown.

This accessor throws no documented exceptions.

Import Requirements

To use layer1.ForEach accessor you must import the module urn:com:1060research:www3:

<import>
  <uri>urn:com:1060research:www3</uri>
</import>

The active:forEach accessor requires a java.lang.Iterable set of resources as its operand. For-each item in the iterable operand set it issues the item to a do request specified with a declarative request.

active:forEach supports synchronous and asynchronous modes for the do request.

Response

By default the response is an ordered set of java.lang.Iterable representations returned by each do-request.

If specified an optional merge request will be called with the list of responses and requires the called merge service to return a single composite resource which is then returned as the response of the active:forEach request (See below).

active:forEach Variants

  • active:forEach - issues do-requests synchronously and fails on any exception in a sub-request
  • active:forEachAsync - issues do-requests asynchronously and fails on any exception in a sub-request
  • active:forEachTolerant - issues do-requests synchronously and tolerates exceptions (see tolerant below)
  • active:forEachAsyncTolerant - issues do-requests asynchronously and tolerates exceptions (see tolerant below)

Tolerant

When using Tolerant processing any exception thrown from the do request is caught and the Exception object is deemed to be the representation returned for that item in the the iterable response set.

If tolerant is not specified, forEach will throw any exception encountered with a do request. Any pending requests will either not be issued (synchronous) or the responses ignored (Asynchronous).

operand

The operand argument must be a java.lang.Iterable. If the implementating iterator has well-defined order then the order is preserved in the resulting iterable response set.

Each entry of the iterable set is regarded as an opaque POJO and is simply relayed on as the arg:item in the do-request (see below).

do

The do argument must be a declarative request. This request will be issued for-each item in the operand set. An item is referenced in the declarative request as arg:item (this is the same pattern as used in relaying arguments in the mapper).

For example the following request to active:groovy would be called for each item in the operand list...

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand">arg:item</argument>
</request>

Treating a String valued item as a reference

If the items in the iterable operand are String values then they may be used as resource references in the do-request by using the from-string method of the declarative request

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand" method="from-string">arg:item</argument>
</request>

arg:index / arg:count

You may pass the index number of the currently processed item in the do-request by specifying arg:index. For example..

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand">arg:item</argument>
  <argument name="index">arg:index</argument>
</request>

You may pass the total item count on the do-request by specifying arg:count. For example..

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand">arg:item</argument>
  <argument name="count">arg:count</argument>
</request>

merge

The optional merge argument must be a declarative request. The merge request will be issued upon completion of all do-requests. The merge request should call a service which will receive the responses from the do-requests and combine them to create a single composite resource. The result from the merge request is relayed as the final response from active:forEach.

The merge request may choose to receive either an iterable set of representations from the do-request by relaying the arg:representations argument. Or equally may choose to receive an iterable list of INKFResponseReadOnly responses by relaying the arg:responses argument. The mode is determined by how the merge request is declared.

Here is an example where the merge request receives an iterable set of representations...

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/mergeRepresentations.gy</argument>
  <argument name="representations">arg:representations</argument>
</request>

Here is an example where the merge request receives an iterable set of responses...

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/mergeResponses.gy</argument>
  <argument name="responses">arg:responses</argument>
</request>

VarArgs Relay

Any additional arguments specified in the request to the active:forEach endpoint may be relayed on to both the do-request and/or merge-request. This is achieved simply by referencing the argument in the declarative request (the same pattern as is used by the mapper).

For example if your request to active:forEach has an argument +foo@bar then this can be relayed in the do-request by...

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand">arg:item</argument>
  <argument name="foo">arg:foo</argument>
</request>

Alternatively, if you just want to forward all additional arguments through to the do-request use the notation ...

<request>
  <identifier>active:groovy</identifier>
  <argument name="operator">res:/processItem.gy</argument>
  <argument name="operand">arg:item</argument>
  <varargs />
</request>

timeout

The optional timeout argument must be transreptable to java.lang.Long and specifies the time in milliseconds to wait for a response from an asynchronous do-request. The timeout argument is only valid for asynchronous processing.

If the timeout period expires and a response has not been received, then there are two possibilities for the handling depending on the Tolerance mode (see above).

  1. If the processing mode is not Tolerant then an exception is thrown and all following do-request responses are ignored.
  2. If the processing mode is Tolerant then the do-request's response is set to be a Java null, any following do-requests are processed as normal.

Fire and Forget Pattern

One possible use for active:forEach is to perform a fan-out of fire-and-forget requests, where each sub-request is issued on its own asynchronous thread and the initiating requestor thread continues with processing with no interest in the responses of the dispatched sub-requests.

To achieve this pattern simply use active:forEachAsyncTolerant and set the timeout to zero. The do-requests will be issued and the intitiating request will immediately return with a null response.