Skip to content

Tutorial Create a basic engine

Sebastien Filion edited this page Jun 13, 2018 · 3 revisions

Create a basic engine

Simply instantiating a Nucleus engine is enough to start interacting with the communication layer but it wouldn't be very useful.

Extend the Nucleus engine with new actions

You can extend the Nucleus engine like any other class and add actions that will be registered during the autodiscovery.

In the following example, you will learn how to create a Ping engine that has only one action called "Ping" and how to call it.

const { NucleusEngine } = require('idex.nucleus');

// Extend the Nucleus engine to create the Ping engine.
class PingEngine extends NucleusEngine {

  constructor () {
    // Name the engine.
    super('Ping');
  }

  /**
   * Pings.
   *
   * @Nucleus ActionName Ping
   *
   * @returns {Promise<{ ping: String }>}
   */
  ping () {

    return Promise.resolve({ ping: 'PING' });
  }

}

async function executePingAction () {
  const $pingEngine = new PingEngine();
  // Create a test engine to publish actions.
  const $testEngine = new NucleusEngine('Test');

  // Wait for both engines to be ready.
  await $pingEngine;
  await $testEngine;

  // Start the autodiscovery on the local directory.
  await $pingEngine.autodiscover(__dirname);
  // Start subscribing to any update made to the action queue.
  await $pingEngine.subscribeToActionQueueUpdate($pingEngine.defaultActionQueueName);

  const dummyUserID = '15808ee9-cb02-4391-99ca-211d29314b31';

  // Read more about the `publishActionByNameAndHandleResponse` method in the engine guide.
  const { ping } = await $testEngine.publishActionByNameAndHandleResponse('Ping', {}, dummyUserID);
  // ping === 'PING'

  return ping;
}

const $$promise = executePingAction();

$$promise
  .catch(console.error)
  .then(process.exit);

Assuming that Redis has been setup correctly, the Test engine will create an action and push it in the action queue for the Ping engine.
Once the Ping engine have executed your action, the publishActionByNameAndHandleResponse will resolve with the response { ping: 'PING' }.

You can confirm that everything went according to plan by digging in Redis a little:

  1. The action has been registered correctly;

    $ redis-cli
    127.0.0.1:6379> HKEYS ActionConfigurationByActionName
    1) "Ping"
    
  2. The action has been completed;

    $ redis-cli
    127.0.0.1:6379> KEYS NucleusAction:Ping:*
    1) "NucleusAction:Ping:d38ba020-5893-11e8-bf03-c38d7bd3fb0e"
    127.0.0.1:6379> HGET NucleusAction:Ping:d38ba020-5893-11e8-bf03-c38d7bd3fb0e status
    "\"Completed\""
    
    127.0.0.1:6379> HGET NucleusAction:Ping:d38ba020-5893-11e8-bf03-c38d7bd3fb0e finalMessage
    "{\"ping\":\"PING\"}"
    

Now that's in the bag, let's try to solve a common use case and create a persistent storage API with its Gateway.