Batch

baja.comm. Batch

new Batch()

Description:
  • A Batch is used to "package up" a number of operations (such as setting a
    Slot value or invoking an Action) into a single network call. Use a Batch
    when you want to be absolutely certain that a group of operations will all
    arrive at the server at the same time, be processed on their own (not
    alongside any other operations that are not part of this Batch), and be
    executed on the server synchronously.

    When interacting with a JACE, it is important to keep the number of
    individual network calls low. This is because the JACE has to do some work
    to receive an HTTP request, whether that request is one byte or 10,000
    bytes. Therefore, by packaging requests into fewer network calls, we reduce
    the CPU load on the JACE and improve response times in the browser.

    Previous to Niagara 4.10, it was required to use a Batch to get
    individual operations to package up into a single network call. However,
    Batches can be easy to forget and add additional complexity to your code.
    Therefore, starting in Niagara 4.10, BajaScript will automatically
    package operations together. Using a technique called "implicit batching",
    operations that occur chronologically close together in the browser will
    get packaged up into a single network call. As of Niagara 4.10, you can
    consider the use of Batches purely for network efficiency as deprecated -
    BajaScript will make network calls efficient by default.

    When operations are batched together, it does not imply any sort of error
    handling. A Batch is not a replacement for Promise.all. Its only job is
    to cut down on network traffic. As long as the one network call
    successfully goes out over the wire and receives a response, each operation
    will still succeed or fail individually.

    Most operations in BajaScript can be batched together. To use a Batch,
    you'll typically pass it in as an argument to a function that supports it.
    Please see the examples.

Source:
Examples

Invoking two actions, using a Batch to make it explicit that the actions should execute on the server at the same time.

var batch = new baja.comm.Batch();

var promise = Promise.all([
  myComp.invoke({ slot: 'thisActionWillSucceed', batch: batch })
    .then(function () { console.log('this message will show'); }),
  myComp2.invoke({ slot: 'thisActionWillFailOnTheStation', batch: batch })
    .catch(function (err) { console.log('this error will show: ' + err); })
]);

// Make a single network call that will invoke both Actions in one go.
// Just because the second action fails on the station and sends back an
// error message, the first action didn't fail along with it just
// because they shared a Batch.
batch.commit();
return promise;

batch.commit() returns its argument. Use this to improve the brevity and readability of your code.

var batch = new baja.comm.Batch();

return batch.commit(Promise.all([
  comp.invoke({ slot: 'action1', batch: batch }),
  comp.invoke({ slot: 'action2', batch: batch })
]));

Here, our only concern is network efficiency. We can call set() as many times as we want. Because we queue everything up at the same time, the set() operations will automatically batch together into a single network call. If other operations also execute at the same time as these set() calls, it's possible they could all also be packaged into the same batch. Prior to Niagara 4.10, each un-batched set() would cause its own network call.

return Promise.all([
  comp.set({ slot: 'slot1', value: 'value1' }),
  comp.set({ slot: 'slot2', value: 'value2' }),
  comp.set({ slot: 'slot3', value: 'value3' })
]);

Here, these two set() calls may not implicitly batch together because they don't happen close to each other chronologically. They will probably go up to the station in two separate network calls.

return Promise.all([
  comp.set({ slot: 'slot1', value: 'value1' }),
  waitSeconds(2)
    .then(function () {
      return comp.set({ slot: 'slot2', value: 'value2' });
    });
]);

The size of a WebSocket message is limited. If there are too many batched operations to fit into a single WebSocket message, BajaScript will automatically split the batch into multiple network calls. They will be reassembled on the other end, and the batch will be processed as normal. Prior to Niagara 4.10, exceeding the WebSocket message size would result in an error.

function addTenThousandSlots(comp) {
  var promises = [];
  for (var i = 0; i < 10000; ++i) {
    promises.push(comp.add({ slot: 'number?', value: i }));
  }
  return Promise.all(promises);
}

Extends

Methods

commit(argopt) → {*}

Description:
  • Sends all BOX requests queued up in this batch across the wire in one
    network call.

    Once called, this batch can no longer have messages or callbacks added, or
    be committed a second time.

Source:
Example

Returning the input arg enables a bit of API cleanliness when returning promises.

//instead of this...
var promise = doABunchOfNetworkCalls(batch);
batch.commit();
return promise;

//do this:
return batch.commit(doABunchOfNetworkCalls(batch));
Parameters:
Name Type Attributes Description
arg * <optional>

an input argument to be returned directly - see example

Throws:

if already committed

Type
Error
Returns:

input arg

Type
*

equals(obj) → {Boolean}

Description:
  • Indicates whether some other object is equal to this one.

Source:
Inherited From:
Parameters:
Name Type Description
obj Object

the reference object with which to compare.

Returns:

true if this object is the same as the obj argument; false otherwise.

Type
Boolean

reserve() → {baja.comm.Batch}

Description:
  • Creates a new batch that will prevent the current batch from sending any
    network calls until the reserve batch itself has been committed. All
    requests on all reserve batches, as well as the current batch, will be
    condensed into a single network call and sent as soon as all reserve
    batches are committed.

    Use this function when you need to add requests to a batch after completing
    some other asynchronous operation. It signals to the original batch, "wait
    for me!"

    The reserved batch's commit() function will not actually send any data.
    It simply signals that your code has finished adding requests to it and
    the original batch is clear to send its data.

Source:
Example

Given a set of relation knobs, I need to resolve each knob's relation ORD and retrieve all relations from the source component. I happen to know that the relation ORDs have already been resolved, so resolving the ORD will not incur a network call, but retrieving relations always does. Therefore, I want to reserve the batch to use on the relations() call.

function retrieveSourceComponentRelations(relationKnob, inpBatch) {
   var reserved = inpBatch.reserve();
   return relationKnob.getRelationOrd().get()
     .then(function (relationSourceComponent) {
       //if I had not reserved a batch, inpBatch would have already been committed
       //by the caller, and this would throw an error.
       var relationsPromise = relationSourceComponent.relations({ batch: reserved });

       //calling commit() on the reserved batch notifies inpBatch that I'm done
       //adding operations, and inpBatch is clear to go ahead and send out the
       //network call.
       reserved.commit();

       return relationsPromise;
     });
}

//now all relations() calls will batch together into a single network call.
var batch = new baja.comm.Batch(),
    promise = Promise.all(allRelationKnobs.map(function (relationKnob) {
      return retrieveSourceComponentRelations(relationKnob, batch);
    }))
      .then(function (relationsResults) {
        relationsResults.forEach(function (relations) { handle(relations); });
      });
batch.commit();
Returns:
Type
baja.comm.Batch

valueOf() → {*}

Description:
  • Return the inner value of the object.

    By default the object's instance is returned.

Source:
Inherited From:
Returns:

the inner value of the object or just the object's instance.

Type
*

(static) reserve(paramsopt) → {baja.comm.Batch}

Description:
  • Reserve a new batch. If an input batch is given (either directly or as a
    batch property of an object), it will create a new reserve batch off
    of that batch. If no input batch is given, this will simply return a new
    batch.

    Use this when your function might have an input batch parameter that you
    want to make use of while still leaving the question of when to commit the
    batch up to the caller.

Source:
Parameters:
Name Type Attributes Description
params baja.comm.Batch | object <optional>

If a batch is given, will reserve
a new batch off of the input batch. Can also be params.batch. Otherwise,
will create a new batch.

Properties
Name Type Attributes Description
batch baja.comm.Batch <optional>
Returns:

either a reserved, or a new batch. It is your
responsibility as the caller to Batch.reserve to commit this batch.

Type
baja.comm.Batch