Gathering detailed insights and metrics for happner-cluster
Gathering detailed insights and metrics for happner-cluster
Gathering detailed insights and metrics for happner-cluster
Gathering detailed insights and metrics for happner-cluster
npm install happner-cluster
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
369 Commits
6 Watching
66 Branches
8 Contributors
Updated on 10 Jan 2022
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
20%
12
Compared to previous day
Last week
-33.6%
71
Compared to previous week
Last month
-85.8%
620
Compared to previous month
Last year
-12%
40,216
Compared to previous year
4
Extends happner with clustering capabilities.
npm install happner-cluster happn-service-mongo-2 —save
Note data service installed separately.
Happner-cluster and happner configs are almost identical excpet that cluster nodes should include a domain name and the happn subconfigs necessary for clustering - as minimum shown below.
For more on happn-cluster subconfig see happn-cluster docs
1var HappnerCluster = require('happner-cluster'); 2 3var config = { 4 5 // name: 'UNIQUE_NAME', // allow default uniqie name 6 domain: 'DOMAIN_NAME', // same as other cluster nodes, used for event replication - allows clusters to be segmented by domain 7 8 cluster: { 9 // requestTimeout: 20 * 1000, // exchange timeouts 10 // responseTimeout: 30 * 1000 11 }, 12 13 happn: { // was "datalayer" 14 services: { 15 data: { 16 // see data sub-config in happn-cluster docs 17 config: { 18 datastores: [ 19 // defaulted by happn-cluster 20 //{ 21 // name: 'mongo', 22 // provider: 'happn-service-mongo-2', 23 // isDefault: true, 24 // settings: { 25 // collection: 'happn-cluster', 26 // database: 'happn-cluster', 27 // url: 'mongodb://127.0.0.1:27017' 28 // url: 'mongodb://username:password@127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/happn?replicaSet=test-set&ssl=true&authSource=admin' 29 // } 30 //}, 31 32 // defaulted by happner-cluster to prevent overwrites in shared db 33 // where each cluster server requires unique data at certain paths 34 //{ 35 // name: 'nedb-own-schema', 36 // settings: {}, 37 // patterns: [ 38 // '/mesh/schema/*', 39 // '/_SYSTEM/_NETWORK/_SETTINGS/NAME', 40 // '/_SYSTEM/_SECURITY/_SETTINGS/KEYPAIR' 41 // ] 42 //} 43 ] 44 } 45 } 46 membership: { 47 // see membership sub-config in happn-cluster docs 48 }, 49 orchestrator: { 50 config: { 51 minimumPeers: minPeers || 3, //minimum peers before stabilise 52 replicate: [ 53 'my-custom-path/*' 54 ] //listen to all cluster events on this path, the following are also listened to by default: 55 // `/_events/${config.domain}/*/*`, 56 // `/_events/${config.domain}/*/*/*`, 57 // `/_events/${config.domain}/*/*/*/*`, 58 // `/_events/${config.domain}/*/*/*/*/*`, 59 // `/_events/${config.domain}/*/*/*/*/*/*`, 60 // `/_events/${config.domain}/*/*/*/*/*/*/*` 61 // NB: to not listen to any cluster events apart from security replication, set replicate: false 62 } 63 } 64 } 65 }, 66 67 modules: { 68 }, 69 70 components: { 71 } 72} 73 74HappnerCluster.create(config).then...
A component that wishes to use non-local components whose instances reside elsewhere in the cluster should declare the dependencies in their package.json
Given a clusternode with component1...
1config = { 2 modules: { 3 'component1': { 4 // using most complex example of module which defines multiple component classes 5 path: 'node-module-name', 6 construct: { 7 name: 'Component1' 8 } 9 } 10 }, 11 components: { 12 'component1': {...} 13 } 14}
…to enable component1 to use remote components from elsewhere in the cluster...
1Component1.prototype.method = function ($happner, callback) { 2 // $happner aka $happn 3 // call remote component not defined locally 4 $happner.exchange['remote-component'].method1(function (e, result) { 5 callback(e, result); 6 }); 7 8 // also 9 // $happner.event['remote-component'].on() .off() .offPath() 10}
…it should declare the dependency in its package.json file…
1// package.json expressed as js 2{ 3 name: 'node-module-name', 4 version: '1.0.0', 5 happner: { 6 dependencies: { 7 'component1': { // the component name which has the dependencies 8 // (allows 1 node_module to define more than 1 mesh component class) 9 'remote-component': { 10 version: '^1.0.0', // will only use matching versions from 11 // elsewhefre in the cluster 12 methods: { // list of methods desired on the remote compnoent - these will not be discovered and will need to be statically defined 13 method1: {}, 14 method2: {} 15 } 16 }, 17 'remote-component2': { 18 version: '~1.0.0' 19 // no methods, only interested in events 20 }, 21 'remote-component3': { 22 version: '~1.0.0' 23 discoverMethods: true //this special switch will result method discovery for the component 24 } 25 } 26 } 27 } 28} 29 30// NB: if method discovery is switched on, inside your component method - where $happn is passed in be aware that the methods may only be available after startup - as the mesh description of the arriving peer on the cluster is used to generate the method api for the discovered component, this means that the declarative approach using $call with $happn should be used to ensure the api does not break, ie: 31 32//dont do this 33await $happn.exchange['remote-component3'].discoveredMethod(arg1, arg2); 34 35 36//rather do this, if the method is not around you can at least handle the method missing error 37try { 38 await $happn.exchange.$call({ 39 component: 'remote-component3', 40 method: 'discoveredMethod', 41 arguments: [arg1, arg2] 42 }); 43} catch (e) { 44 if (e.message === 'invalid endpoint options: [remote-component3.discoveredMethod] method does not exist on the api') { 45 methodMissingHandler(); 46 } 47 throw e; 48}
Note:
Using special syntax in the package.json happner config, it is possible to broker remote dependencies as if they were local components served up by the mesh
The following is an example package.json of a component that is brokering requests to the internal dependency remoteComponent, note the special $broker dependency name, which instructs the cluster to inject remoteComponent into the meshes exchange:
1{ 2 "name": "broker-component", 3 "version": "1.0.1", 4 "happner": { 5 "dependencies": { 6 "$broker": { 7 "remoteComponent": { 8 "version": "^2.0.0", 9 "methods": { 10 "brokeredMethod1": {}, 11 "brokeredEventEmitMethod":{} 12 } 13 } 14 } 15 } 16 } 17}
Based on the above setup, clients are now able to connect to an edge cluster node (which has declared the broker component) and call the brokered dependencies as if they were loaded as components on the edge node:
1 2var client = new Happner.MeshClient({ 3 hostname: 'localhost', 4 port: 8080 5}); 6 7client.login({ 8 username: 'username', 9 password: 'password' 10 }) 11 .then(function () { 12 //NB NB: remoteComponent is now injected into the exchange as if the internal component 13 // were a declared component on the edge cluster node: 14 return client.exchange.remoteComponent.brokeredMethod1(); 15 }) 16 .then(function(result){ 17 //happy days... 18 }) 19
Note:
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 0/8 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
46 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More