@jayesol/jayeson.lib.delivery 2.0.6 → 2.0.7
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/README.md +117 -96
- package/lib/CoreMessages.js +248 -1
- package/lib/DeliveryStack.js +1212 -1
- package/lib/Subscriber.js +1083 -1
- package/lib/index.js +7 -1
- package/lib/util.js +64 -1
- package/package.json +40 -41
package/README.md
CHANGED
|
@@ -1,96 +1,117 @@
|
|
|
1
|
-
v 1.
|
|
2
|
-
- Use
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- Fix
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| Sports Feed
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Braces
|
|
74
|
-
|
|
75
|
-
4.1.
|
|
76
|
-
|
|
77
|
-
Braces
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
1
|
+
v 1.6.0
|
|
2
|
+
- Use netty 4.1 for library to be usable with Java 11.
|
|
3
|
+
- Added stop consumption feature for delivery client to be disconnected from server.
|
|
4
|
+
|
|
5
|
+
v 1.4.1
|
|
6
|
+
- Use StreamFinder 1.6.0: Supports advertisements with paths.
|
|
7
|
+
- New message group for Name Feed: group 30.
|
|
8
|
+
- Prevent streams from getting excluded more than once by having only one ReconnectClientTask.
|
|
9
|
+
- Not to attempt to load truststore if truststores are not provided in the SSL config.
|
|
10
|
+
|
|
11
|
+
v 1.3.9
|
|
12
|
+
- Use StreamFinder 1.4.1 : Sends advertisements containing all unadvertised streams instead of one advertisement per stream.
|
|
13
|
+
- Use StreamFinder 1.5.0 : Split streams inside an advertisement into chunks of 100.
|
|
14
|
+
- Fix memory leak of event loop not garbage collected if connection fails by shutting down the event loop.
|
|
15
|
+
- Fix guice circular dependency between AuthService and AuthGroupProcessor.
|
|
16
|
+
- Fix reconnection missing streams issue #18763.
|
|
17
|
+
- Fix relayer oom issue #19366.
|
|
18
|
+
- Fix disconnection from stream by not sending deregistration request twice #19650
|
|
19
|
+
- Created ConsumptionStopEvent class in Java. An instance will be sent upon successful deregistration from stream.
|
|
20
|
+
- Fixed not able to reconnect to redis server as a result of a change in redis server ip.
|
|
21
|
+
- Added keepalive sending from subscriber to publisher and made sending of keepalive from publisher to subscriber be configurable and default to false.
|
|
22
|
+
|
|
23
|
+
v 1.2.0
|
|
24
|
+
- Use StreamFinder 1.3.0 : Discovering with scope information
|
|
25
|
+
- TypeScript Support for delivery
|
|
26
|
+
- Improved keep-aliv sending. Will only send if there are no other messages sent
|
|
27
|
+
- Bug fixes involving release of reference counted messages, AuthMessage time out. **Config change:** Move `authMsgTimeout` to `authServiceConfig`
|
|
28
|
+
- StreamStopMessage implementation. PE can explictly tell subscriber that it is stopping a stream and subscriber can failover. Refer to wiki for more information
|
|
29
|
+
|
|
30
|
+
v 1.1.2
|
|
31
|
+
- Use StreamFinder 1.2.3
|
|
32
|
+
- Use Netty 4.0.36.Final
|
|
33
|
+
- Support multiple scopes in subscriber(**Update subscriber config**.Will not work with older config)
|
|
34
|
+
- Fixed Reconnection bug in Subscriber where reconnection trying stops after some retries
|
|
35
|
+
- Remove StreamRegistry Group Processing from Eventloop.(No change is needed in PE)
|
|
36
|
+
- To Describing PE callback behavoiur more explcitly:
|
|
37
|
+
- PE should expect messages from an endpoint AFTER call of actOnStreamRegistrationRequest()
|
|
38
|
+
- PE should initiate sending messages ONLY afte call of startPublishing()
|
|
39
|
+
- Subscriber now dont make unnecessary connection to StreamFinder if application is not using subscriber module(i.e If no discovery streams in config).
|
|
40
|
+
- Exposed default handlers in JsonBaseMessageClass. Applications can now extend JSonBaseMessageClass to do custom transformation of message within pipeline itself. E:g [here](https://gitlab.jayeson.com.sg/snippets/7)
|
|
41
|
+
- Added Abstrations for using with jruby
|
|
42
|
+
- Minor bug fixes and improved logging
|
|
43
|
+
|
|
44
|
+
------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
### Registered MessageGroups. Please register your message group before using on common infrastructure
|
|
47
|
+
|
|
48
|
+
| Group | Byte |
|
|
49
|
+
| ------------------------------- | ------ |
|
|
50
|
+
| ObscureGroup(used internally) | 0 |
|
|
51
|
+
| StreamRegistryGroup | 2 |
|
|
52
|
+
| ConnectionCheckingGroup(keep alive) | 4 |
|
|
53
|
+
| Authentication Group | 5 |
|
|
54
|
+
| GenericMessageGroup | 6 |
|
|
55
|
+
| OrderFeed |11 |
|
|
56
|
+
| MinMax Feed |12|
|
|
57
|
+
| Vodds Config Feed |13|
|
|
58
|
+
| Soccer Results Feed |14|
|
|
59
|
+
| Sports Results Feed |15|
|
|
60
|
+
| Name Feed |30|
|
|
61
|
+
| SoccerFeed |69|
|
|
62
|
+
| Ping Pong Feed(Demo Example) |71|
|
|
63
|
+
| Sports Feed |70|
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Develeoper Notes
|
|
67
|
+
|
|
68
|
+
We follow google java style guide
|
|
69
|
+
https://google.github.io/styleguide/javaguide.html
|
|
70
|
+
|
|
71
|
+
Few Points to take note(Copied from style guide ):
|
|
72
|
+
|
|
73
|
+
4.1 Braces
|
|
74
|
+
|
|
75
|
+
4.1.1 Braces are used where optional
|
|
76
|
+
|
|
77
|
+
Braces are used with if, else, for, do and while statements, even when the body is empty or contains only a single statement.
|
|
78
|
+
|
|
79
|
+
4.1.2 Nonempty blocks: K & R style
|
|
80
|
+
|
|
81
|
+
Braces follow the Kernighan and Ritchie style ("Egyptian brackets") for nonempty blocks and block-like constructs:
|
|
82
|
+
|
|
83
|
+
No line break before the opening brace.
|
|
84
|
+
Line break after the opening brace.
|
|
85
|
+
Line break before the closing brace.
|
|
86
|
+
Line break after the closing brace if that brace terminates a statement or the body of a method, constructor or named class. For example, there is no line break after the brace if it is followed by else or a comma.
|
|
87
|
+
|
|
88
|
+
Example:
|
|
89
|
+
|
|
90
|
+
```return new MyClass() {
|
|
91
|
+
@Override public void method() {
|
|
92
|
+
if (condition()) {
|
|
93
|
+
try {
|
|
94
|
+
something();
|
|
95
|
+
} catch (ProblemException e) {
|
|
96
|
+
recover();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};```
|
|
101
|
+
``````
|
|
102
|
+
|
|
103
|
+
### CI/CD guideline
|
|
104
|
+
|
|
105
|
+
#### Publish
|
|
106
|
+
|
|
107
|
+
Guideline: [CI/CD guideline](https://docs.jayeson.com.sg/ops/operations/gitlab-cicd/usage#how-to-use)
|
|
108
|
+
|
|
109
|
+
- Publish for non prod repo:
|
|
110
|
+
```
|
|
111
|
+
publish: snapshot
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- Publish for production repo:
|
|
115
|
+
```
|
|
116
|
+
publish: prod
|
|
117
|
+
```
|
package/lib/CoreMessages.js
CHANGED
|
@@ -1 +1,248 @@
|
|
|
1
|
-
var util=require("./util")
|
|
1
|
+
var util = require("./util")
|
|
2
|
+
var _c = util._c
|
|
3
|
+
var _ = require("underscore")
|
|
4
|
+
var DeliveryStack = require("./DeliveryStack")
|
|
5
|
+
var IMessageGroup = DeliveryStack.IMessageGroup
|
|
6
|
+
var IMessageClass = DeliveryStack.IMessageClass
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This javascript file define some default message group and classes
|
|
10
|
+
* That is commonly used
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/****************** MESSAGE CLASS DEFINITIONS *******************/
|
|
14
|
+
/**
|
|
15
|
+
* Empty Message Class
|
|
16
|
+
*/
|
|
17
|
+
function EmptyMessageClass(group, id) {
|
|
18
|
+
IMessageClass.call(this, group, id, String);
|
|
19
|
+
this.inH = {
|
|
20
|
+
unpack: function (wrapper) { // this unpack method convert undefined to "" for easy handling at processor / hook
|
|
21
|
+
if (wrapper.message === undefined || wrapper.message === null) wrapper.message = "";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
this.outH = {
|
|
26
|
+
pack: function (wrapper) {
|
|
27
|
+
// in whatever case, the message sent in an empty message should
|
|
28
|
+
// be encoded into an empty byte array, regardless of what the user set
|
|
29
|
+
wrapper.message = [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
_c(EmptyMessageClass, {
|
|
34
|
+
inHandlers: function () { // in handlers of the empty message class does nothing
|
|
35
|
+
return [this.inH];
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
outHandlers: function () {
|
|
39
|
+
return [this.outH];
|
|
40
|
+
}
|
|
41
|
+
}, IMessageClass);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* String message class, decode (encode) from byte[] (string) to string (byte[])
|
|
45
|
+
* @param group
|
|
46
|
+
* @param id
|
|
47
|
+
*/
|
|
48
|
+
function StringMessageClass(group, id) {
|
|
49
|
+
EmptyMessageClass.call(this, group, id);
|
|
50
|
+
this.inH = {
|
|
51
|
+
unpack: function (wrapper) {
|
|
52
|
+
var msg = "";
|
|
53
|
+
for (var i = 0; i < wrapper.message.length; i++) {
|
|
54
|
+
msg += String.fromCharCode(wrapper.message[i]);
|
|
55
|
+
}
|
|
56
|
+
wrapper.message = msg;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.outH = {
|
|
61
|
+
pack: function (wrapper) {
|
|
62
|
+
var result = [];
|
|
63
|
+
for (var i = 0; i < wrapper.message.length; i++) {
|
|
64
|
+
result.push(wrapper.message.charCodeAt(i));
|
|
65
|
+
}
|
|
66
|
+
wrapper.message = result;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
_c(StringMessageClass, {
|
|
71
|
+
|
|
72
|
+
outHandlers: function () {
|
|
73
|
+
return [this.outH];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}, EmptyMessageClass);
|
|
77
|
+
|
|
78
|
+
function JSonMessageClass(group, id, instanceClass) {
|
|
79
|
+
IMessageClass.call(this, group, id, String);
|
|
80
|
+
|
|
81
|
+
this.inH = {
|
|
82
|
+
unpack: function (wrapper) {
|
|
83
|
+
// convert from byte[] to json object
|
|
84
|
+
var msg = "";
|
|
85
|
+
for (var i = 0; i < wrapper.message.length; i++) {
|
|
86
|
+
msg += String.fromCharCode(wrapper.message[i]);
|
|
87
|
+
}
|
|
88
|
+
var obj = JSON.parse(msg); // convert into a message
|
|
89
|
+
var actual = new instanceClass();
|
|
90
|
+
_.extend(actual, obj); // copy data into the object of the correct type
|
|
91
|
+
|
|
92
|
+
wrapper.message = actual;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
this.outH = {
|
|
97
|
+
pack: function (wrapper) {
|
|
98
|
+
var msg = JSON.stringify(wrapper.message); // convert original message to string
|
|
99
|
+
var result = [];
|
|
100
|
+
for (var i = 0; i < msg.length; i++) {
|
|
101
|
+
result.push(msg.charCodeAt(i));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
wrapper.message = result; // update wrapper
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
_c(JSonMessageClass, {
|
|
109
|
+
inHandlers: function () {
|
|
110
|
+
return [this.inH];
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
outHandlers: function () {
|
|
114
|
+
return [this.outH];
|
|
115
|
+
}
|
|
116
|
+
}, IMessageClass);
|
|
117
|
+
|
|
118
|
+
/******************** CORE MESSAGE GROUP DEFINITIONS ****************/
|
|
119
|
+
|
|
120
|
+
function GenericMessageGroup() {
|
|
121
|
+
IMessageGroup.call(this, 6);
|
|
122
|
+
this._classes = [
|
|
123
|
+
new StringMessageClass(this, 0)
|
|
124
|
+
];
|
|
125
|
+
};
|
|
126
|
+
_c(GenericMessageGroup, {}, IMessageGroup);
|
|
127
|
+
GenericMessageGroup = new GenericMessageGroup(); // singleton
|
|
128
|
+
|
|
129
|
+
function KeepAliveMessageGroup() {
|
|
130
|
+
IMessageGroup.call(this, 4);
|
|
131
|
+
this._classes = [
|
|
132
|
+
new EmptyMessageClass(this, 0)
|
|
133
|
+
];
|
|
134
|
+
};
|
|
135
|
+
_c(KeepAliveMessageGroup, {}, IMessageGroup);
|
|
136
|
+
KeepAliveMessageGroup = new KeepAliveMessageGroup(); // singleton
|
|
137
|
+
|
|
138
|
+
/**************** AUTH MESSAGE GROUP DEFINITION **********************/
|
|
139
|
+
|
|
140
|
+
// bean definition for the general response
|
|
141
|
+
function GeneralResponse(status, message) {
|
|
142
|
+
this.status = status;
|
|
143
|
+
this.message = message;
|
|
144
|
+
}
|
|
145
|
+
_c(GeneralResponse, {
|
|
146
|
+
getStatus: function () { return this.status; },
|
|
147
|
+
getMessage: function () { return this.message; }
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
//bean definition for the ticket renew
|
|
151
|
+
function TicketRenew(clientId, newTicket) {
|
|
152
|
+
this.clientId = clientId;
|
|
153
|
+
this.newTicket = newTicket;
|
|
154
|
+
}
|
|
155
|
+
_c(GeneralResponse, {
|
|
156
|
+
getClientId: function () { return this.clientId; },
|
|
157
|
+
getNewTicket: function () { return this.newTicket; }
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
function AuthGroup() {
|
|
161
|
+
IMessageGroup.call(this, 5);
|
|
162
|
+
|
|
163
|
+
this.GENERAL_RESPONSE = new JSonMessageClass(this, 0, GeneralResponse);
|
|
164
|
+
this.HTTP_AUTH = new EmptyMessageClass(this, 1);
|
|
165
|
+
this.TCP_AUTH = new EmptyMessageClass(this, 2);
|
|
166
|
+
this.TICKET_RENEW = new JSonMessageClass(this, 3, TicketRenew);
|
|
167
|
+
this.STRING = new StringMessageClass(this, 4);
|
|
168
|
+
|
|
169
|
+
this._classes = [
|
|
170
|
+
this.GENERAL_RESPONSE,
|
|
171
|
+
// this is corresponding HTTP_AUTH_CONTENT, since we are sending auth content
|
|
172
|
+
// using XHR we don't need to define any handlers for this message class
|
|
173
|
+
this.HTTP_AUTH,
|
|
174
|
+
// this correspond to tcp auth content. We are not sending auth content through tcp,
|
|
175
|
+
// so ignore this
|
|
176
|
+
this.TCP_AUTH,
|
|
177
|
+
// ticket renew
|
|
178
|
+
this.TICKET_RENEW,
|
|
179
|
+
// generic string
|
|
180
|
+
this.STRING
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
_c(AuthGroup, {}, IMessageGroup);
|
|
186
|
+
AuthGroup = new AuthGroup(); // singleton
|
|
187
|
+
|
|
188
|
+
/**************** STREAM REGISTRATION GROUP **********************/
|
|
189
|
+
function StreamRegistryRequest(messageGroup, streams, requestType) {
|
|
190
|
+
this.messageGroup = messageGroup;
|
|
191
|
+
this.streams = streams;
|
|
192
|
+
this.requestType = requestType;
|
|
193
|
+
}
|
|
194
|
+
_.extend(StreamRegistryRequest, {
|
|
195
|
+
REGISTRATION: 0,
|
|
196
|
+
CONSUMPTION: 1,
|
|
197
|
+
DEREGISTRATION: 2
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* It is guaranteed by the stream registry service that if I sent a registration message
|
|
202
|
+
* for Group A Stream X, Y, Z, the response will contains the information for all the stream X, Y, Z.
|
|
203
|
+
*
|
|
204
|
+
* @param: messageGroup - the message group i'm registered for
|
|
205
|
+
* @param: streams - a map from stream name to the registration status, can be SUCCESS (4) or FAILED (5)
|
|
206
|
+
* @param: responseType - type of the response, can be REGISTRATION, CONSUMPTION, DEREGISTRATION
|
|
207
|
+
*
|
|
208
|
+
*/
|
|
209
|
+
function StreamRegistryResponse(messageGroup, streams, responseType) {
|
|
210
|
+
this.messageGroup = messageGroup;
|
|
211
|
+
this.streams = streams;
|
|
212
|
+
this.responseType = responseType;
|
|
213
|
+
}
|
|
214
|
+
_.extend(StreamRegistryResponse, {
|
|
215
|
+
REGISTRATION: 0,
|
|
216
|
+
CONSUMPTION: 1,
|
|
217
|
+
STOP_CONSUMPTION: 6,
|
|
218
|
+
DEREGISTRATION: 2,
|
|
219
|
+
GENERAL: 3,
|
|
220
|
+
|
|
221
|
+
SUCCESS: 4,
|
|
222
|
+
FAILED: 5,
|
|
223
|
+
DEREGISTRATION_TIMEOUT: 7
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
function StreamRegistryMessageGroup() {
|
|
227
|
+
IMessageGroup.call(this, 2);
|
|
228
|
+
|
|
229
|
+
this.REQUEST = new JSonMessageClass(this, 0, StreamRegistryRequest);
|
|
230
|
+
this.RESPONSE = new JSonMessageClass(this, 1, StreamRegistryResponse);
|
|
231
|
+
|
|
232
|
+
this._classes = [this.REQUEST, this.RESPONSE];
|
|
233
|
+
}
|
|
234
|
+
_c(StreamRegistryMessageGroup, {}, IMessageGroup); // inherit from IMessageGroup
|
|
235
|
+
StreamRegistryMessageGroup = new StreamRegistryMessageGroup(); // singleton
|
|
236
|
+
|
|
237
|
+
module.exports = exports = {
|
|
238
|
+
StreamRegistryMessageGroup: StreamRegistryMessageGroup,
|
|
239
|
+
EmptyMessageClass: EmptyMessageClass,
|
|
240
|
+
StringMessageClass: StringMessageClass,
|
|
241
|
+
JSonMessageClass: JSonMessageClass,
|
|
242
|
+
StreamRegistryRequest: StreamRegistryRequest,
|
|
243
|
+
StreamRegistryResponse: StreamRegistryResponse,
|
|
244
|
+
AuthGroup: AuthGroup,
|
|
245
|
+
GenericMessageGroup: GenericMessageGroup,
|
|
246
|
+
KeepAliveMessageGroup: KeepAliveMessageGroup,
|
|
247
|
+
TicketRenew: TicketRenew
|
|
248
|
+
}
|