keuss 1.6.14 → 1.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/codeql-analysis.yml +72 -0
- package/Signal.js +6 -0
- package/package.json +4 -3
- package/signal/local.js +76 -3
- package/signal/mongo-capped.js +68 -3
- package/signal/redis-pubsub.js +82 -3
- package/test/signal.js +161 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
+
# to commit it to your repository.
|
|
3
|
+
#
|
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
+
# or to provide custom queries or build logic.
|
|
6
|
+
#
|
|
7
|
+
# ******** NOTE ********
|
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
+
# supported CodeQL languages.
|
|
11
|
+
#
|
|
12
|
+
name: "CodeQL"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [ master ]
|
|
17
|
+
pull_request:
|
|
18
|
+
# The branches below must be a subset of the branches above
|
|
19
|
+
branches: [ master ]
|
|
20
|
+
schedule:
|
|
21
|
+
- cron: '26 13 * * 1'
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
analyze:
|
|
25
|
+
name: Analyze
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
permissions:
|
|
28
|
+
actions: read
|
|
29
|
+
contents: read
|
|
30
|
+
security-events: write
|
|
31
|
+
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
language: [ 'javascript' ]
|
|
36
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
37
|
+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- name: Checkout repository
|
|
41
|
+
uses: actions/checkout@v3
|
|
42
|
+
|
|
43
|
+
# Initializes the CodeQL tools for scanning.
|
|
44
|
+
- name: Initialize CodeQL
|
|
45
|
+
uses: github/codeql-action/init@v2
|
|
46
|
+
with:
|
|
47
|
+
languages: ${{ matrix.language }}
|
|
48
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
49
|
+
# By default, queries listed here will override any specified in a config file.
|
|
50
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
51
|
+
|
|
52
|
+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
53
|
+
# queries: security-extended,security-and-quality
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
57
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
|
58
|
+
- name: Autobuild
|
|
59
|
+
uses: github/codeql-action/autobuild@v2
|
|
60
|
+
|
|
61
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
|
62
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
63
|
+
|
|
64
|
+
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
65
|
+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
66
|
+
|
|
67
|
+
# - run: |
|
|
68
|
+
# echo "Run, Build Application using script"
|
|
69
|
+
# ./location_of_script_within_repo/buildscript.sh
|
|
70
|
+
|
|
71
|
+
- name: Perform CodeQL Analysis
|
|
72
|
+
uses: github/codeql-action/analyze@v2
|
package/Signal.js
CHANGED
|
@@ -73,6 +73,12 @@ class Signal {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
// to be extended: generic pubsub service
|
|
77
|
+
subscribe_extra (topic, on_cb) {return false}
|
|
78
|
+
unsubscribe_extra (subscr) {}
|
|
79
|
+
emit_extra (topic, ev, cb) {if (cb) cb ();}
|
|
80
|
+
|
|
81
|
+
|
|
76
82
|
static _hrtimeAsMSecs (hrtime) {
|
|
77
83
|
return (hrtime[0] * 1000) + (hrtime[1] / 1e6);
|
|
78
84
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keuss",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.15",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"queue",
|
|
6
6
|
"persistent",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"lodash": "~4.17.21",
|
|
35
35
|
"mitt": "~3.0.0",
|
|
36
36
|
"mongodb": "~4.5.0",
|
|
37
|
-
"uuid": "~8.3.2"
|
|
37
|
+
"uuid": "~8.3.2",
|
|
38
|
+
"why-is-node-running": "^2.2.2"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"chance": "~1.1.8",
|
|
@@ -43,6 +44,6 @@
|
|
|
43
44
|
},
|
|
44
45
|
"scripts": {
|
|
45
46
|
"test": "mocha --reporter spec --check-leaks --no-timeouts --exit test/",
|
|
46
|
-
"test-with-coverage": "nyc --reporter=
|
|
47
|
+
"test-with-coverage": "nyc --reporter=html -- mocha --reporter spec --check-leaks --no-timeouts --exit test/"
|
|
47
48
|
}
|
|
48
49
|
}
|
package/signal/local.js
CHANGED
|
@@ -4,6 +4,7 @@ var Signal = require ('../Signal');
|
|
|
4
4
|
var debug = require('debug')('keuss:Signal:local');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
//////////////////////////////////////////////////////////////////////
|
|
7
8
|
class LocalSignal extends Signal {
|
|
8
9
|
constructor (queue, factory, opts) {
|
|
9
10
|
super (queue, opts);
|
|
@@ -39,38 +40,110 @@ class LocalSignal extends Signal {
|
|
|
39
40
|
debug ('created LocalSignal for channel %s', this._channel);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
type () {return LocalSignalFactory.Type ()}
|
|
43
43
|
|
|
44
|
+
//////////////////////////////////////////////////////////////////////
|
|
45
|
+
type () {
|
|
46
|
+
return LocalSignalFactory.Type ();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
//////////////////////////////////////////////////////////////////////
|
|
44
51
|
emitInsertion (mature, cb) {
|
|
45
52
|
debug ('got insertion event [%o], relay on local mitt', mature);
|
|
46
53
|
this._factory._emitter.emit (this._channel, mature.getTime () + '');
|
|
47
54
|
}
|
|
48
55
|
|
|
56
|
+
//////////////////////////////////////////////////////////////////////
|
|
49
57
|
emitPaused (paused, cb) {
|
|
50
58
|
debug ('got paused event [%d], relay on local mitt', paused);
|
|
51
59
|
this._factory._emitter.emit (this._channel, `p ${paused}`);
|
|
52
60
|
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
//////////////////////////////////////////////////////////////////////
|
|
64
|
+
subscribe_extra (topic, on_cb) {
|
|
65
|
+
return this._factory.subscribe_extra (this._master.ns (), topic, on_cb);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
//////////////////////////////////////////////////////////////////////
|
|
70
|
+
unsubscribe_extra (subscr) {
|
|
71
|
+
this._factory.unsubscribe_extra (subscr);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
//////////////////////////////////////////////////////////////////////
|
|
76
|
+
emit_extra (topic, ev, cb) {
|
|
77
|
+
this._factory.emit_extra (this._master.ns (), topic, ev, cb);
|
|
78
|
+
}
|
|
53
79
|
}
|
|
54
80
|
|
|
55
81
|
|
|
82
|
+
//////////////////////////////////////////////////////////////////////
|
|
56
83
|
class LocalSignalFactory {
|
|
57
84
|
constructor (opts) {
|
|
58
85
|
this._emitter = mitt();
|
|
86
|
+
debug ('created local factory');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
//////////////////////////////////////////////////////////////////////
|
|
91
|
+
static Type () {
|
|
92
|
+
return 'signal:local';
|
|
59
93
|
}
|
|
60
94
|
|
|
61
|
-
static Type () {return 'signal:local'}
|
|
62
|
-
type () {return LocalSignalFactory.Type ()}
|
|
63
95
|
|
|
96
|
+
//////////////////////////////////////////////////////////////////////
|
|
97
|
+
type () {
|
|
98
|
+
return LocalSignalFactory.Type ();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
//////////////////////////////////////////////////////////////////////
|
|
64
103
|
signal (queue, opts) {
|
|
65
104
|
return new LocalSignal (queue, this, opts);
|
|
66
105
|
}
|
|
67
106
|
|
|
107
|
+
|
|
108
|
+
//////////////////////////////////////////////////////////////////////
|
|
109
|
+
subscribe_extra (ns, topic, on_cb) {
|
|
110
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
111
|
+
debug ('subscribing to ns [%s], topic [%s]', ns, t);
|
|
112
|
+
|
|
113
|
+
const s = {
|
|
114
|
+
n: ns,
|
|
115
|
+
t: t,
|
|
116
|
+
f: (msg => on_cb (msg))
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
this._emitter.on (s.t, s.f);
|
|
120
|
+
return s;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
//////////////////////////////////////////////////////////////////////
|
|
125
|
+
unsubscribe_extra (s) {
|
|
126
|
+
this._emitter.off (s.t, s.f);
|
|
127
|
+
debug ('unsubscribed on %s', s.t);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
//////////////////////////////////////////////////////////////////////
|
|
132
|
+
emit_extra (ns, topic, ev, cb) {
|
|
133
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
134
|
+
debug ('emit extra on topic [%s], value [%j]', t, ev);
|
|
135
|
+
this._emitter.emit (t, ev);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
//////////////////////////////////////////////////////////////////////
|
|
68
140
|
close (cb) {
|
|
69
141
|
cb ();
|
|
70
142
|
}
|
|
71
143
|
}
|
|
72
144
|
|
|
73
145
|
|
|
146
|
+
//////////////////////////////////////////////////////////////////////
|
|
74
147
|
function creator (opts, cb) {
|
|
75
148
|
return cb (null, new LocalSignalFactory (opts));
|
|
76
149
|
}
|
package/signal/mongo-capped.js
CHANGED
|
@@ -5,7 +5,7 @@ var Signal = require ('../Signal');
|
|
|
5
5
|
|
|
6
6
|
var debug = require('debug')('keuss:Signal:MongoCapped');
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
//////////////////////////////////////////////////////////////////////
|
|
9
9
|
class MCSignal extends Signal {
|
|
10
10
|
constructor (queue, factory, opts) {
|
|
11
11
|
super (queue, opts);
|
|
@@ -45,24 +45,52 @@ class MCSignal extends Signal {
|
|
|
45
45
|
debug ('created mongo-capped signaller for topic %s with opts %o', this._topic_name, opts);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
|
|
49
|
+
//////////////////////////////////////////////////////////////////////
|
|
48
50
|
type () {return MCSignalFactory.Type ()}
|
|
49
51
|
|
|
52
|
+
|
|
53
|
+
//////////////////////////////////////////////////////////////////////
|
|
50
54
|
emitInsertion (mature, cb) {
|
|
51
55
|
debug ('emit insertion on topic [%s] value [%d])', this._topic_name, mature);
|
|
52
56
|
this._factory._channel.publish (this._topic_name, mature.getTime());
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
|
|
60
|
+
//////////////////////////////////////////////////////////////////////
|
|
55
61
|
emitPaused (paused, cb) {
|
|
56
62
|
debug ('emit paused on topic [%s], value [%b]', this._topic_name, paused);
|
|
57
63
|
this._factory._channel.publish (this._topic_name, `p ${paused}`);
|
|
58
64
|
}
|
|
59
65
|
|
|
66
|
+
|
|
67
|
+
//////////////////////////////////////////////////////////////////////
|
|
60
68
|
_insertionEvent (mature) {
|
|
61
69
|
debug ('got insertion event on ch [%s], mature is %s, calling master.emitInsertion()', this._channel, mature);
|
|
62
70
|
this._master.signalInsertion (new Date (mature));
|
|
63
71
|
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
//////////////////////////////////////////////////////////////////////
|
|
75
|
+
subscribe_extra (topic, on_cb) {
|
|
76
|
+
return this._factory.subscribe_extra (this._master.ns (), topic, on_cb);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
//////////////////////////////////////////////////////////////////////
|
|
81
|
+
unsubscribe_extra (subscr) {
|
|
82
|
+
this._factory.unsubscribe_extra (subscr);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
//////////////////////////////////////////////////////////////////////
|
|
87
|
+
emit_extra (topic, ev, cb) {
|
|
88
|
+
this._factory.emit_extra (this._master.ns (), topic, ev, cb);
|
|
89
|
+
}
|
|
64
90
|
}
|
|
65
91
|
|
|
92
|
+
|
|
93
|
+
//////////////////////////////////////////////////////////////////////
|
|
66
94
|
class MCSignalFactory {
|
|
67
95
|
constructor (opts) {
|
|
68
96
|
var defaults = {
|
|
@@ -79,19 +107,56 @@ class MCSignalFactory {
|
|
|
79
107
|
debug ('created mongo-capped factory with opts %o', opts);
|
|
80
108
|
}
|
|
81
109
|
|
|
82
|
-
static Type () {return 'signal:mongo-capped'}
|
|
83
|
-
type () {return MCSignalFactory.Type ()}
|
|
84
110
|
|
|
111
|
+
//////////////////////////////////////////////////////////////////////
|
|
112
|
+
static Type () {
|
|
113
|
+
return 'signal:mongo-capped';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
//////////////////////////////////////////////////////////////////////
|
|
118
|
+
type () {
|
|
119
|
+
return MCSignalFactory.Type ();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
//////////////////////////////////////////////////////////////////////
|
|
85
124
|
signal (channel, opts) {
|
|
86
125
|
return new MCSignal (channel, this, opts);
|
|
87
126
|
}
|
|
88
127
|
|
|
128
|
+
|
|
129
|
+
//////////////////////////////////////////////////////////////////////
|
|
130
|
+
subscribe_extra (ns, topic, on_cb) {
|
|
131
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
132
|
+
debug ('subscribing to ns [%s], topic [%s]', ns, t);
|
|
133
|
+
return this._channel.subscribe (t, on_cb);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
//////////////////////////////////////////////////////////////////////
|
|
138
|
+
unsubscribe_extra (subscr) {
|
|
139
|
+
subscr.unsubscribe ();
|
|
140
|
+
debug ('unsubscribed on %j', subscr);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
//////////////////////////////////////////////////////////////////////
|
|
145
|
+
emit_extra (ns, topic, ev, cb) {
|
|
146
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
147
|
+
debug ('emit extra on ns [%s], topic [%s], value [%j]', ns, t, ev);
|
|
148
|
+
this._channel.publish (t, ev);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
//////////////////////////////////////////////////////////////////////
|
|
89
153
|
close (cb) {
|
|
90
154
|
this._mubsub.close (cb);
|
|
91
155
|
}
|
|
92
156
|
}
|
|
93
157
|
|
|
94
158
|
|
|
159
|
+
//////////////////////////////////////////////////////////////////////
|
|
95
160
|
function creator (opts, cb) {
|
|
96
161
|
return cb (null, new MCSignalFactory (opts));
|
|
97
162
|
}
|
package/signal/redis-pubsub.js
CHANGED
|
@@ -8,6 +8,7 @@ var Signal = require ('../Signal');
|
|
|
8
8
|
var debug = require('debug')('keuss:Signal:RedisPubsub');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
//////////////////////////////////////////////////////////////////////
|
|
11
12
|
class RPSSignal extends Signal {
|
|
12
13
|
constructor (queue, factory, opts) {
|
|
13
14
|
super (queue, opts);
|
|
@@ -53,24 +54,54 @@ class RPSSignal extends Signal {
|
|
|
53
54
|
debug ('created redis-pubsub signaller for topic %s with opts %o', this._topic_name, opts);
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
type () {return RPSSignalFactory.Type ()}
|
|
57
57
|
|
|
58
|
+
//////////////////////////////////////////////////////////////////////
|
|
59
|
+
type () {
|
|
60
|
+
return RPSSignalFactory.Type ();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
//////////////////////////////////////////////////////////////////////
|
|
58
65
|
emitInsertion (mature, cb) {
|
|
59
66
|
debug ('emit insertion on channel [%s] value [%d])', this._channel, mature);
|
|
60
67
|
this._rediscl_pub.publish (this._channel, mature.getTime());
|
|
61
68
|
}
|
|
62
69
|
|
|
70
|
+
|
|
71
|
+
//////////////////////////////////////////////////////////////////////
|
|
63
72
|
emitPaused (paused, cb) {
|
|
64
73
|
debug ('emit paused on channel [%s], value [%b]', this._channel, paused);
|
|
65
74
|
this._rediscl_pub.publish (this._channel, `p ${paused}`);
|
|
66
75
|
}
|
|
67
76
|
|
|
77
|
+
|
|
78
|
+
//////////////////////////////////////////////////////////////////////
|
|
68
79
|
_insertionEvent (mature) {
|
|
69
80
|
debug ('got insertion event on ch [%s], mature is %s, calling master.emitInsertion()', this._channel, mature);
|
|
70
81
|
this._master.signalInsertion (new Date (mature));
|
|
71
82
|
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
//////////////////////////////////////////////////////////////////////
|
|
86
|
+
subscribe_extra (topic, on_cb) {
|
|
87
|
+
return this._factory.subscribe_extra (this._master.ns (), topic, on_cb);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
//////////////////////////////////////////////////////////////////////
|
|
92
|
+
unsubscribe_extra (subscr) {
|
|
93
|
+
this._factory.unsubscribe_extra (subscr);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
//////////////////////////////////////////////////////////////////////
|
|
98
|
+
emit_extra (topic, ev, cb) {
|
|
99
|
+
this._factory.emit_extra (this._master.ns (), topic, ev, cb);
|
|
100
|
+
}
|
|
72
101
|
}
|
|
73
102
|
|
|
103
|
+
|
|
104
|
+
//////////////////////////////////////////////////////////////////////
|
|
74
105
|
class RPSSignalFactory {
|
|
75
106
|
constructor (opts) {
|
|
76
107
|
this._opts = opts || {};
|
|
@@ -86,14 +117,61 @@ class RPSSignalFactory {
|
|
|
86
117
|
debug ('created redis-pubsub factory with opts %o', opts);
|
|
87
118
|
}
|
|
88
119
|
|
|
89
|
-
static Type () {return 'signal:redis-pubsub'}
|
|
90
|
-
type () {return RPSSignalFactory.Type ()}
|
|
91
120
|
|
|
121
|
+
//////////////////////////////////////////////////////////////////////
|
|
122
|
+
static Type () {
|
|
123
|
+
return 'signal:redis-pubsub';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
//////////////////////////////////////////////////////////////////////
|
|
128
|
+
type () {
|
|
129
|
+
return RPSSignalFactory.Type ();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
//////////////////////////////////////////////////////////////////////
|
|
92
134
|
signal (channel, opts) {
|
|
93
135
|
debug ('creating redis-pubsub signaller with opts %o', opts);
|
|
94
136
|
return new RPSSignal (channel, this, opts);
|
|
95
137
|
}
|
|
96
138
|
|
|
139
|
+
|
|
140
|
+
//////////////////////////////////////////////////////////////////////
|
|
141
|
+
subscribe_extra (ns, topic, on_cb) {
|
|
142
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
143
|
+
debug ('subscribing to ns [%s], topic [%s]', ns, t);
|
|
144
|
+
|
|
145
|
+
const s = {
|
|
146
|
+
n: ns,
|
|
147
|
+
t: t,
|
|
148
|
+
f: (msg => on_cb (JSON.parse (msg)))
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
this._emitter.on (s.t, s.f);
|
|
152
|
+
this._rediscl_sub.subscribe (s.t);
|
|
153
|
+
return s;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
//////////////////////////////////////////////////////////////////////
|
|
158
|
+
unsubscribe_extra (subscr) {
|
|
159
|
+
this._rediscl_sub.unsubscribe (subscr.t);
|
|
160
|
+
this._emitter.off (subscr.t, subscr.f);
|
|
161
|
+
debug ('unsubscribed on %j', subscr);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
//////////////////////////////////////////////////////////////////////
|
|
166
|
+
emit_extra (ns, topic, ev, cb) {
|
|
167
|
+
const t = `keuss:signal:${ns}:extra:${topic}`;
|
|
168
|
+
const v = JSON.stringify(ev);
|
|
169
|
+
debug ('emit extra on ns [%s], topic [%s], value [%j]', ns, t, ev);
|
|
170
|
+
this._rediscl_pub.publish (t, v);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
//////////////////////////////////////////////////////////////////////
|
|
97
175
|
close (cb) {
|
|
98
176
|
async.parallel ([
|
|
99
177
|
cb => this._rediscl_pub.quit (cb),
|
|
@@ -103,6 +181,7 @@ class RPSSignalFactory {
|
|
|
103
181
|
}
|
|
104
182
|
|
|
105
183
|
|
|
184
|
+
//////////////////////////////////////////////////////////////////////
|
|
106
185
|
function creator (opts, cb) {
|
|
107
186
|
return cb (null, new RPSSignalFactory (opts));
|
|
108
187
|
}
|
package/test/signal.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const should = require ('should');
|
|
2
|
+
const async = require ('async');
|
|
3
|
+
const _ = require ('lodash');
|
|
4
|
+
|
|
5
|
+
const Local = require ('../signal/local');
|
|
6
|
+
const Redis = require ('../signal/redis-pubsub');
|
|
7
|
+
const Mongo = require ('../signal/mongo-capped');
|
|
8
|
+
|
|
9
|
+
// const whyIsNodeRunning = require('why-is-node-running');
|
|
10
|
+
|
|
11
|
+
const MongoClient = require ('mongodb').MongoClient;
|
|
12
|
+
|
|
13
|
+
// setTimeout (() => whyIsNodeRunning(), 9000)
|
|
14
|
+
|
|
15
|
+
_.forEach ({
|
|
16
|
+
Local,
|
|
17
|
+
Redis,
|
|
18
|
+
Mongo
|
|
19
|
+
}, (CL, CLName) => {
|
|
20
|
+
describe (`${CLName} signaller`, () => {
|
|
21
|
+
|
|
22
|
+
before (done => {
|
|
23
|
+
done();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
after (done => async.series ([
|
|
27
|
+
cb => setTimeout (cb, 1000),
|
|
28
|
+
cb => MongoClient.connect ('mongodb://localhost/keuss_signal', (err, cl) => {
|
|
29
|
+
if (err) return done (err);
|
|
30
|
+
cl.db().dropDatabase (() => cl.close (cb))
|
|
31
|
+
})
|
|
32
|
+
], done));
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
it ('creates ok', done => {
|
|
36
|
+
CL ({}, (err, factory) => {
|
|
37
|
+
if (err) return done(err);
|
|
38
|
+
const q = {ns() {return 'the-ns'}, name () {return 'the-queue'}};
|
|
39
|
+
const signal = factory.signal (q, {});
|
|
40
|
+
setTimeout (() => factory.close(done), 500);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
describe (`extra/generic pubsub`, () => {
|
|
46
|
+
it ('subscribes and receives info ok on 3 subscribers', done => {
|
|
47
|
+
CL ({}, (err, factory) => {
|
|
48
|
+
if (err) return done(err);
|
|
49
|
+
const q = {ns() {return 'the-ns'}, name () {return 'the-queue'}};
|
|
50
|
+
const signal1 = factory.signal (q, {});
|
|
51
|
+
const signal2 = factory.signal (q, {});
|
|
52
|
+
const signal3 = factory.signal (q, {});
|
|
53
|
+
|
|
54
|
+
const evs = [];
|
|
55
|
+
|
|
56
|
+
function manage (ev) {
|
|
57
|
+
evs.push (ev);
|
|
58
|
+
if (evs.length == 3) {
|
|
59
|
+
evs.should.eql ([
|
|
60
|
+
{ a: 1, b: 'ertwetr' },
|
|
61
|
+
{ a: 1, b: 'ertwetr' },
|
|
62
|
+
{ a: 1, b: 'ertwetr' }
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
factory.close(done);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
signal1.subscribe_extra ('the-topic', manage);
|
|
70
|
+
signal2.subscribe_extra ('the-topic', manage);
|
|
71
|
+
signal3.subscribe_extra ('the-topic', manage);
|
|
72
|
+
|
|
73
|
+
setTimeout (() => signal2.emit_extra ('the-topic', {a:1, b:'ertwetr'}), 100);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
it ('functions across several queues on the same signaller', done => {
|
|
79
|
+
CL ({}, (err, factory) => {
|
|
80
|
+
if (err) return done(err);
|
|
81
|
+
const signal1 = factory.signal ({ns() {return 'the-ns'}, name () {return 'the-queue-1'}}, {});
|
|
82
|
+
const signal2 = factory.signal ({ns() {return 'the-ns'}, name () {return 'the-queue-2'}}, {});
|
|
83
|
+
const signal3 = factory.signal ({ns() {return 'the-ns'}, name () {return 'the-queue-3'}}, {});
|
|
84
|
+
|
|
85
|
+
const evs = [];
|
|
86
|
+
|
|
87
|
+
function manage (ev) {
|
|
88
|
+
evs.push (ev);
|
|
89
|
+
if (evs.length == 3) {
|
|
90
|
+
evs.should.eql ([
|
|
91
|
+
{ a: 1, b: 'ertwetr' },
|
|
92
|
+
{ a: 1, b: 'ertwetr' },
|
|
93
|
+
{ a: 1, b: 'ertwetr' }
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
factory.close(done);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
signal1.subscribe_extra ('the-topic', manage);
|
|
101
|
+
signal2.subscribe_extra ('the-topic', manage);
|
|
102
|
+
signal3.subscribe_extra ('the-topic', manage);
|
|
103
|
+
|
|
104
|
+
setTimeout (() => signal2.emit_extra ('the-topic', {a:1, b:'ertwetr'}), 100);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it ('isolates namespaces', done => {
|
|
109
|
+
CL ({}, (err, factory) => {
|
|
110
|
+
if (err) return done(err);
|
|
111
|
+
const signal1 = factory.signal ({ns() {return 'the-ns-1'}, name () {return 'the-queue'}}, {});
|
|
112
|
+
const signal2 = factory.signal ({ns() {return 'the-ns-2'}, name () {return 'the-queue'}}, {});
|
|
113
|
+
|
|
114
|
+
const evs = [];
|
|
115
|
+
|
|
116
|
+
async.series ([
|
|
117
|
+
cb => {signal1.subscribe_extra ('the-topic', ev => evs.push ({src: 1, ev})); cb ();},
|
|
118
|
+
cb => {signal2.subscribe_extra ('the-topic', ev => evs.push ({src: 2, ev})); cb ();},
|
|
119
|
+
cb => setTimeout (() => {signal1.emit_extra ('the-topic', {a:1, b:'qwertyuiop'}); cb ()}, 100),
|
|
120
|
+
cb => setTimeout (() => {signal2.emit_extra ('the-topic', {a:2, b:'asdfghjkl'}); cb ()}, 100),
|
|
121
|
+
cb => setTimeout (cb, 100),
|
|
122
|
+
], err => {
|
|
123
|
+
if (err) return done(err);
|
|
124
|
+
evs.should.eql ([
|
|
125
|
+
{ src: 1, ev: { a: 1, b: 'qwertyuiop' } },
|
|
126
|
+
{ src: 2, ev: { a: 2, b: 'asdfghjkl' } }
|
|
127
|
+
]);
|
|
128
|
+
factory.close(done);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it ('unsubscribes ok and ceases to receive info', done => {
|
|
134
|
+
CL ({}, (err, factory) => {
|
|
135
|
+
if (err) return done(err);
|
|
136
|
+
const signal1 = factory.signal ({ns() {return 'the-ns'}, name () {return 'the-queue'}}, {});
|
|
137
|
+
|
|
138
|
+
const evs = [];
|
|
139
|
+
|
|
140
|
+
function manage (ev) { evs.push (ev); }
|
|
141
|
+
|
|
142
|
+
let subscr = null;
|
|
143
|
+
async.series ([
|
|
144
|
+
cb => {subscr = signal1.subscribe_extra ('the-topic', manage); cb ();},
|
|
145
|
+
cb => setTimeout (() => {signal1.emit_extra ('the-topic', {a:1, b:'ertwetr'}); cb ()}, 100),
|
|
146
|
+
cb => setTimeout (cb, 100),
|
|
147
|
+
cb => {signal1.unsubscribe_extra (subscr); cb (); },
|
|
148
|
+
cb => setTimeout (() => {signal1.emit_extra ('the-topic', {a:2, b:'asdfghjk'}); cb ()}, 100),
|
|
149
|
+
], err => {
|
|
150
|
+
if (err) return done(err);
|
|
151
|
+
evs.should.eql ([ { a: 1, b: 'ertwetr' } ]);
|
|
152
|
+
factory.close(done);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
});
|
|
161
|
+
});
|