Skip to content

Commit 9c31355

Browse files
committed
Fixed purging of all connections in a pool
And make sure connections, returned to the pool, are destroyed after corresponding key has been purged.
1 parent a00aafd commit 9c31355

File tree

2 files changed

+122
-30
lines changed

2 files changed

+122
-30
lines changed

src/v1/internal/pool.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,7 @@ class Pool {
7070
}
7171

7272
purgeAll() {
73-
for (let key in this._pools.keys) {
74-
if (this._pools.hasOwnPropertykey) {
75-
this.purge(key);
76-
}
77-
}
73+
Object.keys(this._pools).forEach(key => this.purge(key));
7874
}
7975

8076
has(key) {
@@ -84,7 +80,8 @@ class Pool {
8480
_release(key, resource) {
8581
let pool = this._pools[key];
8682
if (!pool) {
87-
//key has been purged, don't put it back
83+
// key has been purged, don't put it back, just destroy the resource
84+
this._destroy(resource);
8885
return;
8986
}
9087
if( pool.length >= this._maxIdle || !this._validate(resource) ) {
@@ -96,4 +93,3 @@ class Pool {
9693
}
9794

9895
export default Pool
99-

test/internal/pool.test.js

Lines changed: 119 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ describe('Pool', () => {
3232
const r1 = pool.acquire(key);
3333

3434
// Then
35-
expect( r0.id ).toBe( 0 );
36-
expect( r1.id ).toBe( 1 );
35+
expect(r0.id).toBe(0);
36+
expect(r1.id).toBe(1);
37+
expect(r0).not.toBe(r1);
3738
});
3839

3940
it('pools if resources are returned', () => {
@@ -48,8 +49,9 @@ describe('Pool', () => {
4849
const r1 = pool.acquire(key);
4950

5051
// Then
51-
expect( r0.id ).toBe( 0 );
52-
expect( r1.id ).toBe( 0 );
52+
expect(r0.id).toBe(0);
53+
expect(r1.id).toBe(0);
54+
expect(r0).toBe(r1);
5355
});
5456

5557
it('handles multiple keys', () => {
@@ -67,10 +69,13 @@ describe('Pool', () => {
6769
const r3 = pool.acquire(key2);
6870

6971
// Then
70-
expect( r0.id ).toBe( 0 );
71-
expect( r1.id ).toBe( 1 );
72-
expect( r2.id ).toBe( 0 );
73-
expect( r3.id ).toBe( 2 );
72+
expect(r0.id).toBe(0);
73+
expect(r1.id).toBe(1);
74+
expect(r2.id).toBe(0);
75+
expect(r3.id).toBe(2);
76+
77+
expect(r0).toBe(r2);
78+
expect(r1).not.toBe(r3);
7479
});
7580

7681
it('frees if pool reaches max size', () => {
@@ -96,8 +101,8 @@ describe('Pool', () => {
96101
r2.close();
97102

98103
// Then
99-
expect( destroyed.length ).toBe( 1 );
100-
expect( destroyed[0].id ).toBe( r2.id );
104+
expect(destroyed.length).toBe(1);
105+
expect(destroyed[0].id).toBe(r2.id);
101106
});
102107

103108
it('frees if validate returns false', () => {
@@ -121,9 +126,9 @@ describe('Pool', () => {
121126
r1.close();
122127

123128
// Then
124-
expect( destroyed.length ).toBe( 2 );
125-
expect( destroyed[0].id ).toBe( r0.id );
126-
expect( destroyed[1].id ).toBe( r1.id );
129+
expect(destroyed.length).toBe(2);
130+
expect(destroyed[0].id).toBe(r0.id);
131+
expect(destroyed[1].id).toBe(r1.id);
127132
});
128133

129134

@@ -144,21 +149,111 @@ describe('Pool', () => {
144149
const r1 = pool.acquire(key2);
145150
r0.close();
146151
r1.close();
147-
expect(pool.has(key1)).toBe(true);
148-
expect(pool.has(key2)).toBe(true);
152+
expect(pool.has(key1)).toBeTruthy();
153+
expect(pool.has(key2)).toBeTruthy();
149154
pool.purge(key1);
150-
expect(pool.has(key1)).toBe(false);
151-
expect(pool.has(key2)).toBe(true);
155+
expect(pool.has(key1)).toBeFalsy();
156+
expect(pool.has(key2)).toBeTruthy();
152157

153158
const r2 = pool.acquire(key1);
154159
const r3 = pool.acquire(key2);
155160

156161
// Then
157-
expect( r0.id ).toBe( 0 );
158-
expect( r0.destroyed ).toBe( true );
159-
expect( r1.id ).toBe( 1 );
160-
expect( r2.id ).toBe( 2 );
161-
expect( r3.id ).toBe( 1 );
162+
expect(r0.id).toBe(0);
163+
expect(r0.destroyed).toBeTruthy();
164+
expect(r1.id).toBe(1);
165+
expect(r2.id).toBe(2);
166+
expect(r3.id).toBe(1);
167+
});
168+
169+
it('destroys resource when key was purged', () => {
170+
let counter = 0;
171+
const key = 'bolt://localhost:7687';
172+
const pool = new Pool((url, release) => new Resource(url, counter++, release),
173+
res => {
174+
res.destroyed = true;
175+
return true;
176+
}
177+
);
178+
179+
const r0 = pool.acquire(key);
180+
expect(pool.has(key)).toBeTruthy();
181+
expect(r0.id).toEqual(0);
182+
183+
pool.purge(key);
184+
expect(pool.has(key)).toBeFalsy();
185+
expect(r0.destroyed).toBeFalsy();
186+
187+
r0.close();
188+
expect(pool.has(key)).toBeFalsy();
189+
expect(r0.destroyed).toBeTruthy();
190+
});
191+
192+
it('purges all keys', () => {
193+
let counter = 0;
194+
195+
const key1 = 'bolt://localhost:7687';
196+
const key2 = 'bolt://localhost:7688';
197+
const key3 = 'bolt://localhost:7689';
198+
199+
const pool = new Pool((url, release) => new Resource(url, counter++, release),
200+
res => {
201+
res.destroyed = true;
202+
return true;
203+
}
204+
);
205+
206+
const acquiredResources = [
207+
pool.acquire(key1),
208+
pool.acquire(key2),
209+
pool.acquire(key3),
210+
pool.acquire(key1),
211+
pool.acquire(key2),
212+
pool.acquire(key3)
213+
];
214+
acquiredResources.forEach(resource => resource.close());
215+
216+
pool.purgeAll();
217+
218+
acquiredResources.forEach(resource => expect(resource.destroyed).toBeTruthy());
219+
});
220+
221+
it('skips broken connections during acquire', () => {
222+
let validated = false;
223+
let counter = 0;
224+
const key = 'bolt://localhost:7687';
225+
const pool = new Pool((url, release) => new Resource(url, counter++, release),
226+
res => {
227+
res.destroyed = true;
228+
return true;
229+
},
230+
() => {
231+
if (validated) {
232+
return false;
233+
}
234+
validated = true;
235+
return true;
236+
}
237+
);
238+
239+
const r0 = pool.acquire(key);
240+
r0.close();
241+
242+
const r1 = pool.acquire(key);
243+
expect(r1).not.toBe(r0);
244+
});
245+
246+
it('reports presence of the key', () => {
247+
const existingKey = 'bolt://localhost:7687';
248+
const absentKey = 'bolt://localhost:7688';
249+
250+
const pool = new Pool((url, release) => new Resource(url, 42, release));
251+
252+
pool.acquire(existingKey);
253+
pool.acquire(existingKey);
254+
255+
expect(pool.has(existingKey)).toBeTruthy();
256+
expect(pool.has(absentKey)).toBeFalsy();
162257
});
163258
});
164259

@@ -168,9 +263,10 @@ class Resource {
168263
this.id = id;
169264
this.key = key;
170265
this.release = release;
266+
this.destroyed = false;
171267
}
172268

173269
close() {
174-
this.release(key, self);
270+
this.release(this.key, this);
175271
}
176272
}

0 commit comments

Comments
 (0)