Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: ability to respond with a GIF image from an event

...

When a ruleset shares a KRL function and a user agent (i.e. browser) calls for that function through a /sky/cloud URL, the response is generally a string or a JSON object. The string option is useful when you want a person to see the result of the calculation directly, while the JSON option is best when it will be handled by Javascript code running within the user agent.

The pico engine also performs content negotiation which allows us to add a file extension after the function name (but before arguments in a query string) to indicate how we want the user agent to interpret a string response. Shown here, from top to bottom, with no extension, we see the string, but with a .html extension, the browser interprets that string as a selection box widget, and with a .txt extension, shows it as plain text.

...

Unlike text (whether plain or HTML), an image requires a binary response. The way to prepare a binary response in KRL is to use an Array containing octet values (as decimal numbers between 0 and 255 inclusive). This is supported by the pico engine as of version 0.45.5.

When the pico engine sees a .gif file extension, it will expect such an array, and will present the correct content type (image/gif) and send the bytes computed by your function as the response body. The user agent can then display the image by interpreting those bytes.

...

It is called for by a URL like this one. Notice the file extension .gif added to the function name (See the page on Content negotiation with HTTP).

Code Block
linenumberstrue
http://localhost:8080/sky/cloud/M8LoyVEVaCZenZvJD8GShG/net.sanbachs.counters/number.gif?n=007&bgcolor=[128,0,128]

...

The name D is bound to an array of arrays.

Producing an image from an event

The GIF image in this case has been produced from a function, which the sample ruleset shares. What if we wanted to increment a counter and then return an image of the updated counter value? This involves a mutation of the pico state, and so can only be done in the postlude of a rule triggered by an event.

Experimentally, the engine has been modified to intercept a directive named _gif and, if it is one of the directives produced during event evaluation, instead of returning the array of directives in a JSON object, the engine will produce a proper GIF image response.

Note
titleexperimental feature in version 0.45.6

This feature is recent, so you will need to do a git pull after updating to version 0.45.5, or wait until the feature has been included in version 0.45.6

Here is a rule which will do what is desribed above.

Code Block
linenumberstrue
  rule increment_and_display_counter {
    select when counters hit
    pre {
      new_count = ent:counter.defaultsTo(0) + 1;
      image = number(new_count);
    }
    send_directive("_gif",{"content": image})
    fired {
      ent:counter := new_count;
    }
  }

In line 4, we precompute the new counter value, binding it to the name new_count. No worries about a race condition or critical section, because each event arriving at a pico is evaluating in a single thread.

Line 5 calls the function number to get the array of bytes encoding the new counter value as a GIF image.

The special directive is emitted in line 7, and the new counter value stored in the pico in line 9.