Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mooremachine

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mooremachine - npm Package Compare versions

Comparing version 2.0.1 to 2.1.0

74

lib/fsm.js

@@ -13,6 +13,28 @@ /*

var assert = require('assert-plus');
var util = require('util');
var mod_assert = require('assert-plus');
var mod_crypto = require('crypto');
var mod_util = require('util');
var EventEmitter = require('events').EventEmitter;
var mod_dtrace;
try {
mod_dtrace = require('dtrace-provider');
} catch (e) {
mod_dtrace = undefined;
}
var dt;
if (mod_dtrace !== undefined) {
dt = {};
dt.provider = mod_dtrace.createDTraceProvider('moorefsm');
dt.create = dt.provider.addProbe('create-fsm', 'char *', 'char *');
dt.start = dt.provider.addProbe('transition-start', 'char *', 'char *',
'char *', 'char *');
dt.end = dt.provider.addProbe('transition-end', 'char *', 'char *',
'char *', 'char *');
dt.provider.enable();
}
function FSMStateHandle(fsm, state, link) {

@@ -34,3 +56,3 @@ this.fsh_fsm = fsm;

throw (new Error('FSM validTransitions already set'));
assert.arrayOfString(states, 'states');
mod_assert.arrayOfString(states, 'states');
this.fsh_validTransitions = states;

@@ -178,3 +200,7 @@ };

function FSM(defState) {
assert.string(defState, 'default state');
mod_assert.string(defState, 'default state');
this.fsm_id = FSM.genId();
this.fsm_clsname = this.constructor.name;
if (this.fsm_clsname.length === 0)
this.fsm_clsname = 'FSM';
this.fsm_history = [];

@@ -188,6 +214,21 @@ this.fsm_handle = undefined;

EventEmitter.call(this);
if (dt !== undefined) {
var self = this;
dt.create.fire(function () {
return ([self.fsm_clsname, self.fsm_id]);
});
}
this._gotoState(defState);
}
util.inherits(FSM, EventEmitter);
mod_util.inherits(FSM, EventEmitter);
FSM.genId = function () {
var b = mod_crypto.randomBytes(8);
/*
* Use slice() to strip off the trailing "=" padding, as the last 2
* chars are always the same and make for unnecessary noise.
*/
return (b.toString('base64').slice(0, 11));
};
FSM.prototype.getState = function () {

@@ -203,3 +244,3 @@ return (this.fsm_state);

FSM.prototype.allStateEvent = function (evt) {
assert.string(evt, 'event');
mod_assert.string(evt, 'event');
if (this.fsm_allStateEvents === undefined)

@@ -212,6 +253,6 @@ this.fsm_allStateEvents = [];

FSM.prototype._gotoState = function (state) {
assert.string(state, 'state');
mod_assert.string(state, 'state');
if (this.fsm_inTransition) {
assert.ok(this.fsm_nextState === undefined);
mod_assert.ok(this.fsm_nextState === undefined);
this.fsm_nextState = state;

@@ -221,2 +262,11 @@ return;

var self = this;
var oldState = this.fsm_state;
if (dt !== undefined) {
dt.start.fire(function () {
return ([self.fsm_clsname, self.fsm_id,
oldState, state]);
});
}
/*

@@ -283,3 +333,2 @@ * First, kill event handlers and timers from our previous state, as

var self = this;
this.fsm_allStateEvents.forEach(function (evt) {

@@ -305,2 +354,9 @@ if (self.listeners(evt).length < 1) {

if (dt !== undefined) {
dt.end.fire(function () {
return ([self.fsm_clsname, self.fsm_id,
oldState, state]);
});
}
var next = this.fsm_nextState;

@@ -307,0 +363,0 @@ if (next !== undefined) {

5

package.json
{
"name": "mooremachine",
"version": "2.0.1",
"version": "2.1.0",
"description": "Moore finite state machines",

@@ -34,2 +34,5 @@ "main": "lib/index.js",

},
"optionalDependencies": {
"dtrace-provider": "~0.8"
},
"devDependencies": {

@@ -36,0 +39,0 @@ "tape": ">=3.5.0 <4.0.0"

@@ -289,1 +289,131 @@ mooremachine

sub-state) as usual before entering the new state.
DTrace support
--------------
Mooremachine has support for DTrace probes using `dtrace-provider` (and
`libusdt`). The following probes are provided under the
`moorefsm$pid` provider:
* `create-fsm(char *klass, char *id)` -- fired at the creation of a new FSM
instance. The `klass` argument contains the string name of the constructor
of the FSM sub-class. The `id` argument contains a short randomly generated
string that should be unique to this FSM as long as <~6M instances of this
class exist in the program (it consists of 64 random bits, base64-encoded,
so about a 1/1M chance of collision at 6M instances).
* `transition-start(char *klass, char *id, char *oldState, char *newState)` --
fired at the beginning of an FSM transitioning to a new state.
* `transition-end(char *klass, char *id, char *oldState, char *newState)` --
fired at the end of an FSM transitioning to a new state.
For example:
```
dtrace -Zc 'node thingfsm.js' -n '
moorefsm$target:::transition-start
/copyinstr(arg0) == "ThingFSM"/
{
printf("%s => %s", copyinstr(arg2), copyinstr(arg3));
}'
```
When used on the `ThingFSM` above might output:
```
CPU ID FUNCTION:NAME
4 8216 transition-start:transition-start undefined => stopped
4 8216 transition-start:transition-start stopped => connecting
4 8216 transition-start:transition-start connecting => error
```
This is will list all the transitions of `ThingFSM` instances.
Another example (as a d-script file):
```
uint64_t timeIn[string];
moorefsm$target:::transition-start
/copyinstr(arg0) == "SocketMgrFSM" && copyinstr(arg2) != "undefined"/
{
this->id = copyinstr(arg1);
this->state = copyinstr(arg2);
this->entryTime = timeIn[this->id];
this->exitTime = timestamp;
this->time = (this->exitTime - this->entryTime) / 1000000;
@timeInState[this->state] = quantize(this->time);
}
moorefsm$target:::transition-end
/copyinstr(arg0) == "SocketMgrFSM"/
{
this->id = copyinstr(arg1);
timeIn[this->id] = timestamp;
}
```
This reports on the number of milliseconds spent in each state by
all SocketMgrFSM instances in the process.
The output from this could look like:
```
$ dtrace -Zc 'node test.js' -s script.d
...
error
value ------------- Distribution ------------- count
-1 | 0
0 |@@@@@@@@@@@@@@@@@@@@ 1
1 | 0
2 |@@@@@@@@@@@@@@@@@@@@ 1
4 | 0
backoff
value ------------- Distribution ------------- count
-1 | 0
0 |@@@@@@@@@@@@@@@@@@@@ 1
1 | 0
2 | 0
4 | 0
8 | 0
16 | 0
32 | 0
64 |@@@@@@@@@@@@@@@@@@@@ 1
128 | 0
connected
value ------------- Distribution ------------- count
2 | 0
4 |@@@@@@@@@@@ 2
8 |@@@@@@ 1
16 | 0
32 | 0
64 | 0
128 | 0
256 |@@@@@@ 1
512 |@@@@@@@@@@@@@@@@@ 3
1024 | 0
connecting
value ------------- Distribution ------------- count
-1 | 0
0 |@@@@@@@@@@@@@@@@@@ 4
1 |@@@@ 1
2 | 0
4 | 0
8 | 0
16 | 0
32 | 0
64 |@@@@ 1
128 | 0
256 |@@@@ 1
512 |@@@@ 1
1024 |@@@@ 1
2048 | 0
```
It's generally safe enough to use only the `id` of the FSM as a key in an
associative array or aggregation in DTrace, even when tracing multiple
processes. This only becomes a problem if you expect to have more than a few
million FSMs running at the same time on a system (in which case you can scope
it by pid and class as well as key).
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc