@@ -8,14 +8,27 @@ const _ = require('lodash')
8
8
const assert = require ( 'assert' )
9
9
const uuid = require ( 'uuid' )
10
10
const zookeeper = require ( 'node-zookeeper-client' )
11
+ const listeners = [ 'leader' , 'follower' ]
11
12
12
13
describe ( 'Elector' , function ( ) {
13
14
let electors = [ ]
14
15
15
- afterEach ( function ( ) {
16
- for ( let elector of electors ) {
17
- elector . disconnect ( )
18
- }
16
+ afterEach ( function ( done ) {
17
+ async . each (
18
+ electors ,
19
+ function ( elector , callback ) {
20
+ elector . removeAllListeners ( listeners )
21
+ if ( elector . disconnecting ) {
22
+ return callback ( null )
23
+ }
24
+
25
+ elector . disconnect ( callback )
26
+ if ( ! elector . ownsClient ) {
27
+ elector . client . close ( )
28
+ }
29
+ } ,
30
+ done
31
+ )
19
32
} )
20
33
21
34
it ( 'should elect one node out of the five as leader' , function ( done ) {
@@ -33,6 +46,59 @@ describe('Elector', function () {
33
46
} )
34
47
} )
35
48
49
+ it ( 'should still have one leader after some nodes leave' , function ( done ) {
50
+ electors = _ . times ( 5 , createElector )
51
+
52
+ assert ( electors . length , 5 )
53
+
54
+ const leaders = [ ]
55
+ const followers = [ ]
56
+
57
+ async . series (
58
+ [
59
+ function ( callback ) {
60
+ connectAndListen ( electors , leaders , followers , function ( error ) {
61
+ assert . equal ( leaders . length , 1 )
62
+ assert . equal ( followers . length , 4 )
63
+ callback ( error )
64
+ } )
65
+ } ,
66
+
67
+ function ( callback ) {
68
+ const disconnectNodes = _ . sampleSize ( electors , 2 )
69
+ async . each (
70
+ disconnectNodes ,
71
+ function ( elector , callback ) {
72
+ elector . removeAllListeners ( listeners )
73
+ elector . disconnect ( callback )
74
+ } ,
75
+ callback
76
+ )
77
+ }
78
+ ] ,
79
+ function ( ) {
80
+ let leaders = 0
81
+ let followers = 0
82
+ let disconnected = 0
83
+ for ( let elector of electors ) {
84
+ if ( elector . isLeader ) {
85
+ leaders ++
86
+ } else {
87
+ followers ++
88
+ }
89
+ if ( elector . disconnecting ) {
90
+ disconnected ++
91
+ }
92
+ }
93
+
94
+ assert . equal ( leaders , 1 )
95
+ assert . equal ( followers , 4 )
96
+ assert . equal ( disconnected , 2 )
97
+ done ( )
98
+ }
99
+ )
100
+ } )
101
+
36
102
it ( 'should take an existing zookeeper client' , function ( done ) {
37
103
const electionPath = '/' + uuid . v4 ( )
38
104
electors = _ . times ( 5 , function ( ) {
@@ -70,8 +136,8 @@ function connectAndListen (electors, leaders, followers, callback) {
70
136
}
71
137
callback ( null )
72
138
}
73
- elector . on ( 'leader' , cb )
74
- elector . on ( 'follower' , cb )
139
+ elector . once ( 'leader' , cb )
140
+ elector . once ( 'follower' , cb )
75
141
elector . on ( 'error' , callback )
76
142
} ,
77
143
callback
0 commit comments