@@ -8,6 +8,7 @@ var FlamebaseDatabase = require("flamebase-database-node");
8
8
var Path = require ( "./model/path.js" ) ;
9
9
var apply = require ( 'rus-diff' ) . apply ;
10
10
var clone = require ( 'rus-diff' ) . clone ;
11
+ var sha1 = require ( 'sha1' ) ;
11
12
12
13
JSON . stringifyAligned = require ( 'json-align' ) ;
13
14
@@ -17,16 +18,21 @@ String.prototype.replaceAll = function(search, replacement) {
17
18
} ;
18
19
19
20
var expectedDBNEnvVar = "DATABASE_NAME" ;
20
- var expectedPORTNEnvVar = "DATABASE_PORT" ;
21
+ var expectedPORTEnvVar = "DATABASE_PORT" ;
22
+ var expectedAPIKeyEnvVar = "API_KEY" ;
21
23
var dbMaster = null ;
22
24
var port = null ;
25
+ var APIKey = null ;
23
26
24
27
process . argv . forEach ( function ( val , index , array ) {
25
28
if ( val . indexOf ( expectedDBNEnvVar ) > - 1 ) {
26
29
dbMaster = val . replaceAll ( expectedDBNEnvVar + "=" , "" ) ;
27
30
}
28
- if ( val . indexOf ( expectedPORTNEnvVar ) > - 1 ) {
29
- port = val . replaceAll ( expectedPORTNEnvVar + "=" , "" ) ;
31
+ if ( val . indexOf ( expectedPORTEnvVar ) > - 1 ) {
32
+ port = val . replaceAll ( expectedPORTEnvVar + "=" , "" ) ;
33
+ }
34
+ if ( val . indexOf ( expectedAPIKeyEnvVar ) > - 1 ) {
35
+ APIKey = val . replaceAll ( expectedAPIKeyEnvVar + "=" , "" ) ;
30
36
}
31
37
} ) ;
32
38
@@ -35,7 +41,6 @@ var TAG = "SERVER CLUSTER";
35
41
var logger = log4js . getLogger ( TAG ) ;
36
42
37
43
var dbPaths = "paths" ;
38
- var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
39
44
40
45
if ( cluster . isMaster ) {
41
46
@@ -58,7 +63,8 @@ if (cluster.isMaster) {
58
63
59
64
var action = {
60
65
response : function ( connection , data , error , pId ) {
61
- var result = { status : ( data === null || error !== null ? "KO" : "OK" ) , data : data , error : error } ;
66
+ var result = { status : ( data === null || error !== null ? "KO" : "OK" ) ,
67
+ data : ( data === null ? { } : data ) , error : error } ;
62
68
logger . info ( "worker: " + pId ) ;
63
69
logger . info ( "response: " + JSON . stringify ( result ) ) ;
64
70
connection . response . contentType ( 'application/json' ) ;
@@ -68,7 +74,12 @@ if (cluster.isMaster) {
68
74
this . addGreatListener ( connection , pId ) ;
69
75
} ,
70
76
addGreatListener : function ( connection , pId ) {
77
+ var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
78
+ paths . syncFromDatabase ( ) ;
79
+ logger . debug ( JSON . stringifyAligned ( paths . ref ) ) ;
71
80
paths . syncFromDatabase ( ) ;
81
+ logger . debug ( "getting" ) ;
82
+ logger . debug ( JSON . stringifyAligned ( paths . ref ) ) ;
72
83
73
84
if ( paths . ref === undefined ) {
74
85
paths . ref = { }
@@ -92,27 +103,86 @@ if (cluster.isMaster) {
92
103
paths . ref [ key ] . tokens [ connection . token ] . os = connection . os ;
93
104
}
94
105
106
+ var keys = Object . keys ( paths . ref [ key ] . tokens ) ;
107
+ var lastChangeTime = 0 ;
108
+ var lastToken = null ;
109
+
110
+ for ( var i = keys . length - 1 ; i >= 0 ; i -- ) {
111
+ var time = paths . ref [ key ] . tokens [ keys [ i ] ] . time ;
112
+ if ( lastChangeTime < time ) {
113
+ lastChangeTime = time ;
114
+ lastToken = keys [ i ] ;
115
+ }
116
+ }
117
+
95
118
paths . ref [ key ] . tokens [ connection . token ] . time = new Date ( ) . getTime ( ) ;
96
119
97
120
paths . syncToDatabase ( ) ;
98
121
122
+ var equals = this . verifyLenght ( connection , pId ) ;
123
+
99
124
var object = this . getReference ( connection , pId ) ;
100
125
object . FD . syncFromDatabase ( ) ;
101
126
var len = 0 ;
127
+
102
128
if ( typeof object !== "string" ) {
103
129
len = JSON . stringify ( object . FD . ref ) . length ;
130
+ } else {
131
+ this . response ( connection , null , object , pId ) ;
132
+ return ;
104
133
}
134
+
105
135
var data = { } ;
106
136
data . len = len ;
107
- data . info = "listener_added" ;
137
+
138
+ if ( lastToken === connection . token && equals ) {
139
+ data . info = "listener_up_to_date" ;
140
+ } else {
141
+ data . info = "listener_ready_for_refresh_client" ;
142
+ }
108
143
109
144
this . response ( connection , data , null , pId ) ;
110
145
} else {
111
146
this . response ( connection , null , "path_contains_dots" , pId ) ;
112
147
}
113
148
114
149
} ,
150
+ verifyLenght : function ( connection , pId ) {
151
+ var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
152
+ paths . syncFromDatabase ( ) ;
153
+ var object = this . getReference ( connection , pId ) ;
154
+ // var len = JSON.stringify(object.FD.ref).length;
155
+ logger . debug ( sha1 ( JSON . stringify ( object . FD . ref ) ) . toUpperCase ( ) ) ;
156
+ logger . debug ( connection . sha1 ) ;
157
+
158
+ var hash = sha1 ( JSON . stringify ( object . FD . ref ) ) . toUpperCase ( ) ;
159
+ return hash === connection . sha1 ;
160
+ } ,
161
+ getUpdatesFrom : function ( connection , pId ) {
162
+ var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
163
+ paths . syncFromDatabase ( ) ;
164
+ logger . debug ( "getting" ) ;
165
+ logger . debug ( JSON . stringifyAligned ( paths . ref ) ) ;
166
+ var object = this . getReference ( connection , pId ) ;
167
+ if ( typeof object === "string" ) {
168
+ this . response ( connection , null , object , pId ) ;
169
+ } else {
170
+ var device = {
171
+ token : connection . token ,
172
+ os : connection . os
173
+ }
174
+ object . sendUpdateFor ( connection . content , device )
175
+ var data = { } ;
176
+ data . info = "updates_sent" ;
177
+ data . len = JSON . stringify ( object . FD . ref ) . length ;
178
+ this . response ( connection , data , null , pId ) ;
179
+ }
180
+ } ,
115
181
updateData : function ( connection , pId ) {
182
+ var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
183
+ paths . syncFromDatabase ( ) ;
184
+ logger . debug ( "getting" ) ;
185
+ logger . debug ( JSON . stringifyAligned ( paths . ref ) ) ;
116
186
var object = this . getReference ( connection , pId ) ;
117
187
if ( typeof object === "string" ) {
118
188
this . response ( connection , null , object , pId ) ;
@@ -125,40 +195,43 @@ if (cluster.isMaster) {
125
195
logger . debug ( JSON . stringify ( differences ) ) ;
126
196
apply ( object . FD . ref , JSON . parse ( differences ) ) ;
127
197
128
- if ( JSON . stringify ( object . FD . ref ) . length < connection . len ) {
129
- logger . error ( "##########_inconsistency_length" ) ;
130
- this . response ( connection , null , "inconsistency_length" , pId ) ;
131
- return ;
198
+ if ( JSON . stringify ( object . FD . ref ) . length !== connection . len ) {
199
+ object . FD . syncToDatabase ( ) ;
200
+ this . response ( connection , null , "data_updated_with_differences" , pId ) ;
201
+ } else {
202
+ object . FD . syncToDatabase ( ) ;
203
+ this . response ( connection , "data_updated" , null , pId ) ;
132
204
}
133
-
134
- object . FD . syncToDatabase ( ) ;
135
-
136
- this . response ( connection , "data_updated" , null , pId ) ;
137
205
} else {
138
206
this . response ( connection , "no_diff_updated" , null , pId ) ;
139
207
}
140
208
}
141
209
} ,
142
210
getReference : function ( connection , pId ) {
211
+ var paths = new FlamebaseDatabase ( dbPaths , "/" ) ;
212
+ paths . syncFromDatabase ( ) ;
213
+ var error = null ;
143
214
if ( connection . path !== undefined ) {
144
215
if ( connection . path . indexOf ( "\." ) === - 1 ) {
145
216
if ( connection . path . indexOf ( "/" ) === 0 ) {
146
217
var key = connection . path . replaceAll ( "/" , "\." ) ;
147
218
key = key . substr ( 1 , key . length - 1 ) ;
148
219
if ( paths . ref [ key ] !== undefined ) {
149
- return new Path ( paths . ref [ key ] , dbMaster , connection . path , pId ) ;
220
+ return new Path ( APIKey , paths . ref [ key ] , dbMaster , connection . path , pId ) ;
150
221
} else {
151
- return "holder_not_found" ;
222
+ error = "holder_not_found" ;
152
223
}
153
224
} else {
154
- return "path_not_starts_with_slash" ;
225
+ error = "path_not_starts_with_slash" ;
155
226
}
156
227
} else {
157
- return "path_contains_dots" ;
228
+ error = "path_contains_dots" ;
158
229
}
159
230
} else {
160
- return "json_path_not_found" ;
231
+ error = "json_path_not_found" ;
161
232
}
233
+ logger . error ( error ) ;
234
+ return error ;
162
235
} ,
163
236
parseRequest : function ( req , res , worker ) {
164
237
var response = res ;
@@ -193,6 +266,11 @@ if (cluster.isMaster) {
193
266
logger . debug ( "path: " + connection [ key ] ) ;
194
267
break ;
195
268
269
+ case "sha1" :
270
+ connection [ key ] = message [ key ] ;
271
+ logger . debug ( "sha1: " + connection [ key ] ) ;
272
+ break ;
273
+
196
274
case "token" :
197
275
connection [ key ] = message [ key ] ;
198
276
logger . debug ( "token: " + connection [ key ] ) ;
@@ -203,6 +281,11 @@ if (cluster.isMaster) {
203
281
logger . debug ( "differences: " + connection [ key ] ) ;
204
282
break ;
205
283
284
+ case "content" :
285
+ connection [ key ] = message [ key ] ;
286
+ logger . debug ( "content: " + connection [ key ] ) ;
287
+ break ;
288
+
206
289
case "len" :
207
290
connection [ key ] = message [ key ] ;
208
291
logger . debug ( "len: " + connection [ key ] ) ;
@@ -213,6 +296,11 @@ if (cluster.isMaster) {
213
296
logger . debug ( "os: " + connection [ key ] ) ;
214
297
break ;
215
298
299
+ case "clean" :
300
+ connection [ key ] = message [ key ] ;
301
+ logger . debug ( "clean: " + connection [ key ] ) ;
302
+ break ;
303
+
216
304
default :
217
305
218
306
//
@@ -253,6 +341,15 @@ if (cluster.isMaster) {
253
341
}
254
342
break ;
255
343
344
+ case "get_updates" :
345
+ try {
346
+ this . getUpdatesFrom ( connection , worker ) ;
347
+ } catch ( e ) {
348
+ logger . error ( "there was an error parsing request from getUpdatesFrom: " + e . toString ( ) ) ;
349
+ this . response ( connection , null , "cluster_" + worker + "_error_getting_updates" , worker ) ;
350
+ }
351
+ break ;
352
+
256
353
default :
257
354
//
258
355
break ;
@@ -287,7 +384,6 @@ if (cluster.isMaster) {
287
384
} ) ;
288
385
289
386
app . listen ( port , function ( ) {
290
- paths . syncFromDatabase ( ) ;
291
387
logger . info ( "server cluster started on port " + port + " on " + cluster . worker . id + " worker" ) ;
292
388
} ) ;
293
389
}
0 commit comments