Quantcast
Channel: Intel Developer Zone Articles
Viewing all articles
Browse latest Browse all 3384

Thought Processes Overview and Examples

$
0
0

Understanding Thought Processes
     THOPs 1.0
     THOPs 2.0

THOPs Examples
     THOPs 1.0
          Example 1: Hello World
          Example 2: Hello Stranger
          Example 3: Connections Query
          Example 4: Connections Query with Built-Ins
     THOPs 2.0
          Example 1: Asynchronous Connections
          Example 2: Long-Running Asynchronous Connections
 

Understanding Thought Processes

Saffron Technology™ Thought Processes (THOPs) are user-defined functions that allow you to tie together various SaffronMemoryBase™ and other capabilities using a scripting language. Thought Processes can help perform a wide variety of actions such as: simplifying the execution of complex sequential queries, calling outside applications to be used in conjunction with Saffron Technology reasoning functions, or converting query results into data suitable for UI widgets. THOPs are written in one of the supported script languages (currently, only JavaScript is available).

If you are familiar with other database products, think of Thought Processes as stored procedures. THOPs can be created via the REST API or by using the developer tools in Saffron Admin. After a Thought Process is defined, it becomes callable through the standard REST API.

Currently, SaffronMemoryBase includes two versions of Thought Processes: THOPs 1.0 and THOPs 2.0.

THOPs 1.0

These Thought Processes are run synchronously. THOPs 1.0 runs via an HTTP GET call with the calling client and waits for a result.

Synchronous THOP diagram

THOPs 1.0 are called using a GET operation and uses the Tomcat application server. This version is based on the Rhino JavaSript engine with extensions.

Use THOPs 1.0 for the following types of operations:

  • Simple single queries
  • Fast operations 
  • Where asynchronization is not necessary

THOPs 2.0

The THOPs 2.0 layer enables Thought Processes to run asynchronously and to have bi-directional communication with the calling client. The processes can be long-running, which is why we refer to them as Deep Thoughts (DT). When initiated by a caller, DTs can run arbitrarily long and can send messages to the client before delivering a final result.

The following is an example of a Deep Thought that can deliver a partial result to the calling client as soon as data is available and deliver the remaining results later:

Deep Thought diagram sending messages to caller

Deep Thoughts can also listen to messages being sent by the caller and reply to those messages individually (as well as return partial or final results).

Here, THOPs can register for messages from the caller. THOPs can also reply to messages or send messages proactively:

Deep Thought message exchange with caller

Clients start an instance of a Deep Thought (DT) by POSTing to the thopname/result resource. The result of the POST does not contain a final result, but an Event Bus address to listen for messages from the DT as well as a start address. Clients then send a message to the start address to actually start the DT (it lies dormant to give the client a chance to register to the listen address).

Deep Thought POST

A DT can send a (partial) result to the client using the send(data) function. data is any JS object; it will be turned into JSON during transmission to the client.

A DT can register for messages sent by the client after the DT was started using the on(address, handler) function. Address is any string that the client uses to send messages to the DT. DT's handler will then be called with the message as well as a replyHandler. The DT can use the replyHandler to send a message back to the calling client. (Alternatively, it can use the send function.)

As part of default parameters for a DT, a timeout value can be specified after which a DT instance shuts down (and the client will be unable to send messages to the DT).

Use THOPs 2.0 for the following types of operations:

  • Complex queries that cannot be expressed in a single query
  • Business logic when writing apps based on SUIT and THOPS
  • Integrating SaffronMemoryBase APIs and foreign APIs
  • Using a stored procedure in a relational database
  • Deploying code at run time

THOPs Examples

THOPs 1.0

Below is an example of the THOPs 1.0 layer. Note that this is primarily used for SaffronMemoryBase 10.x and runs only synchronous Thought Processes:

THOPs 1.0 layer

Example 1: Hello World

File: HelloWorld.js

function run() {
     return 'Hello World!';
}

Line 1: A THOP must have at least one function. In THOPs 1.0, the start function must be named run() 

           (The function is runAsync(…) for THOPs 2.0.)

Line 2: Return result. This can be a string or an object (which will be turned into JSON)

To run:  

  curl –u username ‘http://localhost:8080/ws/rest/proc/HelloWorld/result?access_key=demo’

Result format:

  var data = {
        result: “Hello World”,
        debug: [{ … }],
        error: {…} or “”
    }

In order to turn the result into a JS object on the client side, run JSON.parse(data.result) !

Example 2: Hello Stranger

File: HelloStranger.js

function run(p) {
     debug (p);
     return 'Hello ' + p.name;
}

Line 1: The first argument is a map of all parameters of the query part of the URL used in calling the THOP.

Line 2: Thought Processes include a built-in debug(…) function. Debug info is delivered as part of the result.

Line 3: The optional parameter p contains a map of key-value pairs that are specified when calling the Thought Process.

Example 3: Connections Query

File: connections.js

function run(p) {
     var smb = new Smb('http://mhtn01.saffrontech.org:8080/ws', '******', '12345');
     var result = smb.connections('jira_all_saffron').q('project_key:suit').get();
     return result.r.map(attr).value();
 }

function attr(r) {
     return r.a.c + ':' + r.a.v;

}

Line 2: Create a connection to a SaffronMemoryBase cluster using an access_key (******) and secret (12345).

Line 3: Run a connections query on space jira_all_saffron with an AQL query project_key:suit. (The function q(...) is used to specify an AQL query.) The call to get() makes the actual call to the REST service. The resulting parsed JSON object is stored in the result variable.

Line 4: Use lo-dash to map the result to a list of category:values (see http://lodash.com/):

  • result.r contains an array of attributes which are connected with project_key:suit in our example.
  • Behind the scenes, the call to get() wraps this array as a lo-dash object and adds a map(...) function. Map calls the attr(...) function for each element in the array and builds a new array out of the return values.
  • attr(...) is a function that turns an object like the one above into an AQL-compatible string and then returns it.
  • The call to value() unwraps the object and returns the raw array.

Example 4: Connections Query with Built-Ins

File: connections-2.js

 function run(p) {
  var result = connections('jira_all_saffron').q('project_key:suit').get();
     return result.r.map(attr).value();
 }

 function attr(r) {
     return r.a.c + ':' + r.a.v;
 }

Instead of creating your own SaffronMemoryBase connection object (as in Example 3), you can use the built-in connections that then connects to your local SaffronMemoryBase instance.

  local.connections(…)  is connections(…)

THOPs 2.0

Below is an example of the THOPs 2.0 layer. This supports asynchronous Thought Processes:

THOPs 2.0 layer

Example 1: Asynchronous Connections

function runAsync(p, cb) {
      var smb = new Smb('http://mhtn01.saffrontech.org:8080/ws', 'demo', '12345');
      var result = smb.connections('jira_all_saffron').q('project_key:suit').then(
          function (result) {
              debug(result);
              cb(result.r.map(attr).value());
          }
       );
  }

function attr(r) {
     return r.a.c + ':' + r.a.v;
 }

Line 1: The first argument is a map of all parameters of the query part of the URL used in calling the THOP. In THOPs 2.0, the function is runAsync(…)

Line 2: Create a connection to a SaffronMemoryBase cluster using an access_key (******) and secret (12345).

Line 3: Run a connections query on space jira_all_saffron with an AQL query project_key:suit. (The function q(...) is used to specify an AQL query.) Instead of using GET when you create the connection, use then or async then.

Line 4: The result function is the callback (cb) handler. This function is called with the final result of the connection call at some point in the future.

Example 2: Long-Running Asynchronous Connections

 function runAsync(p, cb) {
     on('marco', function(data){
         send('polo');
     });
     on('quit', function(data){
         cb('thanks!');
     });
 }

Some connections can run forever. They can also register events from the caller.

Line 2: The on function is used to register for an event that is private to this connection.

Line 3: The send function is used to send a message to the calling client.


Viewing all articles
Browse latest Browse all 3384

Trending Articles