Have ideas to improve npm?Join in the discussion! »

    @nodeframe/seneca

    2.2.20 • Public • Published

    Seneca wrapper for ES6 and promise application

    Create and maintain by Nodeframe Solution

    Contact us at support@nf-solution.com

    NOTE: This lib had been migrated from nfs-seneca which is officially depreciated. The development and maintenance will continue solely on this repo.

    Installation

    npm install @nodeframe/seneca --save

    Usage

    import

    import nfsSeneca from '@nodeframe/seneca';

    declare the seneca using this syntax

    const {add, act, si} = nfsSeneca(option, transportConfig)

    The last value si is the seneca object itself returned from the seneca initialization.

    the implementation of si object is like so

      const si = seneca(option)

    and it simply return out for you to use, you can still use si.use(), si.client(), or si.listen() as same as you would use with the official seneca object

    The add and act is simply the wrapped version of si.add and si.act

    Usage Example

    You can declare a service with function,promise and async function

    import nfsSeneca from '@nodeframe/seneca';
    const {add,act,si} = nfsSeneca(config.seneca.options, config.seneca.transport);
     
    add({...}, (args,done) => {
        done(null,{role:'With Done'});
    });
     
    add({...}, (args) => {
      return Promise.resolve('resolved');
    });
     
    add({...}, (args) => {
      return {role:'With Return'};
    });
     
    add({...}, async (args){
      return await p1();
    });

    Config

    There's two type of config that should be pass upon initialization

    The first part is the seneca option passed to the seneca initialization. This config will be passed directly to the official seneca initialization. The transportConfig is where all the magic happen.

    the transport config can be like this

    transports: {
     listenings: [
       {
         type: 'http',
         pins: [
           { role: 'portals', cmd: '*' }
         ],
         port: '8000',
         timeout: 30000
       }
     ],
     clients: [
       {
         type: 'http',
         pins: [
           { role: 'serviceX', cmd: '*'}
         ],
         port: '8000',
         host: process.env.APPLICATION_SERVICE || 'application_service',
         timeout: 30000
       },
       {
         type: 'http',
         pins: [
           { role: 'serviceY', cmd: '*' }
         ],
         port: '8000',
         host: process.env.USER_SERVICE || 'user_service',
         timeout: 30000
       }
     ]
    }

    note that this config is compatible with seneca plugins as well, for example you can use seneca-amqp-transport plugin (note that this plugin must be npm install on your main project in order to get this to work)

    The example of this amqp transport config can be like so

    transports: {
      listenings: [],
      clients: [
       {
         type: 'amqp',
         timeout: 5000,
         pins: [
           { role: 'USER', cmd: '*' },
           { role: 'permalinkSubmission', cmd: '*' }
         ],
         url: process.env.AMQP_URL || 'amqp://guest:guest@128.199.105.153:5672'
       }
      ]
     uses: ['seneca-amqp-transport']
    }

    The seneca.use('seneca-amqp-transport') will be run upon initialization by this library.

    Plugin

    The other seneca plugin that require more initialization step shall be declared in this package, currently we have several plugin that capable for initialization simply by pushing config file to this setup (of course, you still need to npm install the plugin into the main project as well)

    Mesh

    This plugin will use kubernetes mesh for seneca

    These npm seneca plugins are required for this plugin to work

    "seneca-balance-client":
    "seneca-consul-registry"
    "seneca-mesh"
    

    The mesh initialization on seneca must be run in this manner

    seneca
      .use('consul-registry',{
        host: 'consul-host'
      })
      .use('mesh',{
        pins:[ //listening role
          'role:a',
          'role:b',
          'role:c',
        ],
        host:'host-name-for-this-service',
        bases:[
          'base-service-host:39999'
        ],
        discover:{
          registry:{
            active: true
          },
          multicast:{
            active: false
          }
        } //other option here
      })
      .ready(function(){
        //ready function
      })

    To avoid duplicate code on your seneca initialization, these setting shall settle in your config only

    const config = {
      transports: {
        type: 'mesh',
        listenings: [
          {
            pins: [
              { role: 'a', cmd: '*' },
              { role: 'b', cmd: '*' },
              { role: 'c', cmd: '*' }
            ]
          }
        ],
        clients: [],
        consul: {
          host: 'consul-host'
        },
        mesh: {
          host: 'host-name-for-this-service',
          bases: ['base-service-host:39999']
        },
        option: {
          //option in this will be merged
          discover:{
            registry:{
              active: true
            },
            multicast:{
              active: false
            }
          }
        }
      }
    }

    notice the mesh.host is the mandatory field that should specify about this service host name so that other service can connect to this service. The bases array is the base center service according to mesh architecture.

    HealthCheck

    It is important for seneca service to check if the other service to call is available or not. On the contrary, each service should provide a simple health checking for other servie to check if the communication can be made. This will help savign quite some time during debugging process.

    @nodeframe/seneca try to add a mean to handle this problem. When you pass the config into @nodeframe/seneca, it will automatically read which listening pins this current service provides. It then create another special add for each pins.

    For example, passing this config to @nodeframe/seneca

    const seneca = nfsSeneca({}, {
      listenings: [
        {
          type: 'http',
          pins: [
            { role: 'a', cmd: '*' },
            { role: 'b', cmd: '*' },
            { role: 'c', cmd: 'cee' }
          ]
        }
      ],
      clients: [
        {
          type: 'http',
          pins: [{role: 'd', cmd: '*'}]
        }
      ]
    })

    passing this, the health check function will be registered to these pins

    { role: 'a', cmd: '_healthCheck' }
    { role: 'b', cmd: '_healthCheck' }

    for other service you can ping to check if this service is online by running this

    seneca.act({role: 'a', cmd: '_healthCheck'}, function(err, response) {
      console.log(response.result)
      //will return {timestamp: <<the current time>>, service: 'a'}
    })
     

    Note that role: c will not register any healthCheck because it could not be sure that all the pins will come into this service, hence there could be clashes on _healthCheck method. Moreover, note that the role: d will not be registered also sine it is a service that this current service will consume (not the provider).

    To add manual health check to this service, you can do it by sending healthCheck config like so

    const seneca = nfsSeneca({}, {
      healthCheck: ['a', 'b']
    })

    doing this will add cmd: _healthCheck to role a and b

    Lastly, if you are not interested in the health check, you can disable it by passing

    const seneca = nfsSeneca({}, {
      disableHealthCheck: true
    })

    HealthCheck Log Pulse

    if you want to see the log pulse of _healthCheck, you should pass

    const seneca = nfsSeneca({}, {
      logHealthCheckPulse: "true"
    })

    with this, your application will log something like this every health check pulse

    run healthcheck resursively to:  payment,MAIL,property,USER,TASK,portals
     
    USER is available at 2017-12-11T21:37:06.691Z
     
    TASK is available at 2017-12-11T21:37:06.691Z
     
    MAIL is available at 2017-12-11T21:37:06.691Z
     
    payment is available at 2017-12-11T21:37:06.692Z
     
    property is available at 2017-12-11T21:37:06.692Z
     
    portals is available at 2017-12-11T21:37:06.695Z

    Ping function

    to help you debug the service, we develop a ping function that can pass the same config and ping to the client service

    var ping = require('@nodeframe/seneca/libs/tool').getPing(senecaOption, transportConfig)

    then, this function can be used to call to health check on the specify service

    ping('a').then(function(resp) {
      console.log("resp=", resp)
    })

    will call to service a

    Keywords

    none

    Install

    npm i @nodeframe/seneca

    DownloadsWeekly Downloads

    288

    Version

    2.2.20

    License

    ISC

    Unpacked Size

    237 kB

    Total Files

    35

    Last publish

    Collaborators

    • avatar
    • avatar
    • avatar
    • avatar
    • avatar