Managing the allocation of users to computer instances, whether in Docker or AWS, can be a complex task. Users have the ability to increase the number of instances and change user assignments within those instances. Each instance is assigned a weight percentage for distribution purposes.
- Users: 10
- Locations: 2 [{loc1.weight: 70%}, {loc2.weight: 30%}] which equates to having 7 users in one location and 3 in the other.
The total weight percentage may not always add up to 100, so a scale factor needs to be considered for adjustments.
One important requirement is that each instance must have at least 1 user. There's a condition in place ensuring that the minimum number of users cannot be less than the number of locations.
Another key aspect is that all users should be assigned as integers.
Example
Case #1
Users: 5
Locations: 4 where 1.weight = 15, 2.weight = 30, 3.weight = 15, 4.weight = 50 (total weight 110%)
Expected Results
Locations:
1.users = 1,
2.users = 1,
3.users = 1,
4.users = 2
Case #2
Users: 10
Locations: 4 where 1.weight = 10, 2.weight = 10, 3.weight = 90, 4.weight = 10 (total weight 120%)
Expected Results
Locations:
1.users = 1,
2.users = 1,
3.users = 7,
4.users = 1
Case #3
Users: 5
Locations: 2 where 1.weight = 50, 2.weight = 50
Expected Results
Locations:
1.users = 3,
2.users = 2
This problem has been approached using a JavaScript function shown below:
function updateUsers(clients, weights) {
let remainingClients = clients;
const maxWeight = weights.reduce((total, weight) => total + parseInt(weight), 0);
let r = [];
weights.forEach(weight => {
let expectedClient = Math.round(clients * (weight / maxWeight));
let val = remainingClients <= expectedClient ? remainingClients : expectedClient;
remainingClients -= expectedClient;
r.push(val > 0 ? val : 1);
});
if (remainingClients > 0) {
r = r.sort((a, b) => a > b ? 1 : -1);
for (let i = 0; i < remainingClients; i++) {
r[i] = r[i] + 1;
}
}
return r;
}
While this function works well with certain numbers like
updateUsers(12, [5, 5, 5, 90]);
producing the output
[1, 1, 1, 9]; //total 12 users
it may not handle extreme cases smoothly such as
updateUsers(12, [5, 5, 5, 200]);
resulting in
[2, 1, 1, 11]; //total 15 users which is incorrect