Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,8 @@ CueBallConnectionPool.prototype._rebalance = function () {
if (target > this.p_max)
target = this.p_max;

var plan = mod_utils.planRebalance(conns, self.p_dead, target,
self.p_max);
var plan = mod_utils.planRebalance(conns, self.p_keys, self.p_dead,
target, self.p_max);

if (plan.remove.length > 0 || plan.add.length > 0) {
this.p_log.trace('rebalancing pool, remove %d, ' +
Expand Down
3 changes: 2 additions & 1 deletion lib/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ CueBallConnectionSet.prototype._rebalance = function () {
});

var plan = mod_utils.planRebalance(
conns, this.cs_dead, this.cs_target, this.cs_max, true);
conns, this.cs_keys, this.cs_dead, this.cs_target, this.cs_max,
true);

if (plan.remove.length > 0 || plan.add.length > 0) {
this.cs_log.trace('rebalancing cset, remove %d, ' +
Expand Down
11 changes: 7 additions & 4 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,27 +220,30 @@ function shuffle(array) {
* - `remove` -- Array of Object, connections to be closed
*
* Parameters:
* - `connections` -- an Object, map of String (backend id) to Array of Object
* (connections), list of currently open connections
* - `inSpares` -- an Object, map of String (backend id) to Array of Object
* (connections), list of currently open connections
* - `backendKeys` -- an Array, containing keys ordered by decreasing
* preference
* - `dead` -- an Object, map of String (backend id) to Boolean, true when a
* a given backend is declared dead
* - `target` -- a Number, target number of connections we want to have
* - `max` -- a Number, maximum socket ceiling
* - `singleton` -- optional Boolean (default false), create only a single
* connection per distinct backend. used for Sets.
*/
function planRebalance(inSpares, dead, target, max, singleton) {
function planRebalance(inSpares, backendKeys, dead, target, max, singleton) {
var replacements = 0;
var wantedSpares = {};

mod_assert.object(inSpares, 'connections');
mod_assert.arrayOfString(backendKeys, 'backendKeys');
mod_assert.number(target, 'target');
mod_assert.number(max, 'max');

mod_assert.ok(target >= 0, 'target must be >= 0');
mod_assert.ok(max >= target, 'max must be >= target');

var keys = Object.keys(inSpares);
var keys = backendKeys.slice();

var plan = { add: [], remove: [] };

Expand Down
143 changes: 123 additions & 20 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ mod_tape.test('rebalance: simple addition', function (t) {
var spares = {
'b1': []
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b1'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b1', 'b1', 'b1']);
t.end();
Expand All @@ -25,7 +28,11 @@ mod_tape.test('rebalance: addition over 2 options', function (t) {
'b1': [],
'b2': []
};
var plan = mod_utils.planRebalance(spares, {}, 5, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 5, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b1', 'b1', 'b2', 'b2']);
t.end();
Expand All @@ -36,7 +43,11 @@ mod_tape.test('rebalance: add with existing', function (t) {
'b1': ['c1'],
'b2': ['c2']
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b2']);
t.end();
Expand All @@ -47,7 +58,11 @@ mod_tape.test('rebalance: add none', function (t) {
'b1': ['c1', 'c3'],
'b2': ['c2', 'c4']
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, []);
t.end();
Expand All @@ -58,7 +73,11 @@ mod_tape.test('rebalance: add and remove', function (t) {
'b1': ['c1', 'c2', 'c3'],
'b2': ['c4']
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.equal(plan.remove.length, 1);
t.ok(['c1', 'c2', 'c3'].indexOf(plan.remove[0]) !== -1);
t.deepEqual(plan.add, ['b2']);
Expand All @@ -70,7 +89,11 @@ mod_tape.test('rebalance: add from unbalanced', function (t) {
'b1': ['c1', 'c2', 'c3'],
'b2': ['c4']
};
var plan = mod_utils.planRebalance(spares, {}, 6, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 6, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b2', 'b2']);
t.end();
Expand All @@ -81,7 +104,11 @@ mod_tape.test('rebalance: shrink', function (t) {
'b1': ['c1', 'c2', 'c3'],
'b2': ['c4', 'c5', 'c6']
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.deepEqual(plan.remove, ['c4', 'c1']);
t.deepEqual(plan.add, []);
t.end();
Expand All @@ -97,7 +124,16 @@ mod_tape.test('rebalance: lots of nodes', function (t) {
'b6': [],
'b7': []
};
var plan = mod_utils.planRebalance(spares, {}, 5, 10);
var keys = [
'b1',
'b2',
'b3',
'b4',
'b5',
'b6',
'b7'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 5, 10);
t.deepEqual(plan.remove, ['c1', 'c2', 'c3']);
t.deepEqual(plan.add, ['b2', 'b3', 'b4', 'b5']);
t.end();
Expand All @@ -113,7 +149,16 @@ mod_tape.test('rebalance: more nodes', function (t) {
'b6': [],
'b7': []
};
var plan = mod_utils.planRebalance(spares, {}, 6, 10);
var keys = [
'b3',
'b1',
'b2',
'b4',
'b5',
'b6',
'b7'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 6, 10);
t.deepEqual(plan.remove, ['c1', 'c2', 'c3']);
t.deepEqual(plan.add, ['b3', 'b1', 'b2', 'b4', 'b6']);
t.end();
Expand All @@ -129,7 +174,16 @@ mod_tape.test('rebalance: excess spread out', function (t) {
'b6': ['c6'],
'b7': []
};
var plan = mod_utils.planRebalance(spares, {}, 3, 10);
var keys = [
'b3',
'b1',
'b2',
'b4',
'b5',
'b6',
'b7'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 3, 10);
t.deepEqual(plan.remove, ['c6', 'c5', 'c4']);
t.deepEqual(plan.add, []);
t.end();
Expand All @@ -141,7 +195,12 @@ mod_tape.test('rebalance: odd number', function (t) {
'b1': [],
'b2': []
};
var plan = mod_utils.planRebalance(spares, {}, 4, 10);
var keys = [
'b3',
'b1',
'b2'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 4, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b3', 'b1', 'b2']);
t.end();
Expand All @@ -153,7 +212,12 @@ mod_tape.test('rebalance: re-ordering', function (t) {
'b1': ['c1'],
'b3': ['c2']
};
var plan = mod_utils.planRebalance(spares, {}, 2, 10);
var keys = [
'b2',
'b1',
'b3'
];
var plan = mod_utils.planRebalance(spares, keys, {}, 2, 10);
t.deepEqual(plan.remove, ['c2']);
t.deepEqual(plan.add, ['b2']);
t.end();
Expand All @@ -165,10 +229,15 @@ mod_tape.test('rebalance: dead replacement', function (t) {
'b2': [],
'b3': []
};
var keys = [
'b1',
'b2',
'b3'
];
var dead = {
'b1': true
};
var plan = mod_utils.planRebalance(spares, dead, 2, 10);
var plan = mod_utils.planRebalance(spares, keys, dead, 2, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b2', 'b3']);
t.end();
Expand All @@ -180,10 +249,15 @@ mod_tape.test('rebalance: dead replacement and shrink', function (t) {
'b2': ['c2'],
'b3': []
};
var keys = [
'b1',
'b2',
'b3'
];
var dead = {
'b1': true
};
var plan = mod_utils.planRebalance(spares, dead, 3, 10);
var plan = mod_utils.planRebalance(spares, keys, dead, 3, 10);
t.deepEqual(plan.remove, ['c1']);
t.deepEqual(plan.add, ['b2', 'b3']);
t.end();
Expand All @@ -194,10 +268,14 @@ mod_tape.test('rebalance: dead again', function (t) {
'b1': ['c1'],
'b2': ['c2']
};
var keys = [
'b1',
'b2'
];
var dead = {
'b1': true
};
var plan = mod_utils.planRebalance(spares, dead, 1, 2);
var plan = mod_utils.planRebalance(spares, keys, dead, 1, 2);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, []);
t.end();
Expand All @@ -210,11 +288,17 @@ mod_tape.test('rebalance: nested dead', function (t) {
'b3': [],
'b4': []
};
var keys = [
'b1',
'b2',
'b3',
'b4'
];
var dead = {
'b1': true,
'b3': true
};
var plan = mod_utils.planRebalance(spares, dead, 2, 10);
var plan = mod_utils.planRebalance(spares, keys, dead, 2, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b3', 'b4']);
t.end();
Expand All @@ -227,11 +311,17 @@ mod_tape.test('rebalance: nested dead with cap', function (t) {
'b3': [],
'b4': []
};
var keys = [
'b1',
'b2',
'b3',
'b4'
];
var dead = {
'b1': true,
'b3': true
};
var plan = mod_utils.planRebalance(spares, dead, 2, 3);
var plan = mod_utils.planRebalance(spares, keys, dead, 2, 3);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b1', 'b4']);
t.end();
Expand All @@ -241,10 +331,13 @@ mod_tape.test('rebalance: dead, backend starvation', function (t) {
var spares = {
'b1': ['c1']
};
var keys = [
'b1'
];
var dead = {
'b1': true
};
var plan = mod_utils.planRebalance(spares, dead, 2, 10);
var plan = mod_utils.planRebalance(spares, keys, dead, 2, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, []);
t.end();
Expand All @@ -255,10 +348,14 @@ mod_tape.test('rebalance: dead, backend starvation', function (t) {
'b1': ['c1'],
'b2': []
};
var keys = [
'b1',
'b2'
];
var dead = {
'b1': true
};
var plan = mod_utils.planRebalance(spares, dead, 3, 10);
var plan = mod_utils.planRebalance(spares, keys, dead, 3, 10);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, ['b2', 'b2', 'b2']);
t.end();
Expand All @@ -271,13 +368,19 @@ mod_tape.test('bug #30', function (t) {
'ashWtupYHh1QH33UP/T2+6hvi8c=': [],
'4QMg6SChOmtF8s6lfK32lLoKUFs=': []
};
var keys = [
'16uN6JsJFild9cHyl2+LSyRHmNc=',
'c7QG0UOYCpm6m/hYUX0jBenbM70=',
'ashWtupYHh1QH33UP/T2+6hvi8c=',
'4QMg6SChOmtF8s6lfK32lLoKUFs='
];
var dead = {
'c7QG0UOYCpm6m/hYUX0jBenbM70=': true,
'16uN6JsJFild9cHyl2+LSyRHmNc=': true,
'4QMg6SChOmtF8s6lfK32lLoKUFs=': true,
'ashWtupYHh1QH33UP/T2+6hvi8c=': true
};
var plan = mod_utils.planRebalance(spares, dead, 3, 4);
var plan = mod_utils.planRebalance(spares, keys, dead, 3, 4);
t.deepEqual(plan.remove, []);
t.deepEqual(plan.add, [
'ashWtupYHh1QH33UP/T2+6hvi8c=', '4QMg6SChOmtF8s6lfK32lLoKUFs=']);
Expand Down