(control) JSON serializes Map<Integer> to Map<Double> and Java gets confused
This commit is contained in:
parent
044bcf55bd
commit
e927f99777
@ -43,32 +43,32 @@ public class RebalanceActor extends AbstractActorPrototype {
|
||||
|
||||
@ActorState(name= INIT, next = CALCULATE_TRANSACTIONS, resume = ActorResumeBehavior.ERROR,
|
||||
description = "Fetches the number of domains assigned to each eligible processing node")
|
||||
public Map<Integer, Integer> getPopulations() throws Exception {
|
||||
public List<Pop> getPopulations() throws Exception {
|
||||
return getNodePopulations();
|
||||
}
|
||||
|
||||
@ActorState(name= CALCULATE_TRANSACTIONS, next = END, resume = ActorResumeBehavior.ERROR,
|
||||
description = "Calculates how many domains to re-assign between the processing nodes"
|
||||
)
|
||||
public List<Give> calculateTransactions(Map<Integer, Integer> populations) {
|
||||
public List<Give> calculateTransactions(List<Pop> populations) {
|
||||
|
||||
if (populations.size() <= 1) {
|
||||
transition(END);
|
||||
}
|
||||
|
||||
int average = (int) populations.values().stream().mapToInt(Integer::valueOf).average().orElse(0);
|
||||
int average = (int) populations.stream().mapToInt(pop -> pop.count).average().orElse(0);
|
||||
int tolerance = average / 10;
|
||||
|
||||
PriorityQueue<Sur> surplusList = new PriorityQueue<>();
|
||||
PriorityQueue<Def> deficitList = new PriorityQueue<>();
|
||||
|
||||
populations.forEach((node, count) -> {
|
||||
int delta = count - average;
|
||||
populations.forEach(pop -> {
|
||||
int delta = pop.count - average;
|
||||
if (delta - tolerance > 0) {
|
||||
surplusList.add(new Sur(node, delta));
|
||||
surplusList.add(new Sur(pop.node, delta));
|
||||
}
|
||||
else if (delta + tolerance < 0) {
|
||||
deficitList.add(new Def(node, -delta));
|
||||
deficitList.add(new Def(pop.node, -delta));
|
||||
}
|
||||
});
|
||||
|
||||
@ -94,7 +94,7 @@ public class RebalanceActor extends AbstractActorPrototype {
|
||||
return actions;
|
||||
}
|
||||
|
||||
private Map<Integer, Integer> getNodePopulations() throws SQLException {
|
||||
private List<Pop> getNodePopulations() throws SQLException {
|
||||
Map<Integer, Integer> ret = new HashMap<>();
|
||||
|
||||
try (var conn = dataSource.getConnection();
|
||||
@ -118,7 +118,7 @@ public class RebalanceActor extends AbstractActorPrototype {
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret.entrySet().stream().map(e -> new Pop(e.getKey(), e.getValue())).toList();
|
||||
}
|
||||
|
||||
private boolean isNodeExcluded(NodeConfiguration node) {
|
||||
@ -163,6 +163,9 @@ public class RebalanceActor extends AbstractActorPrototype {
|
||||
}
|
||||
}
|
||||
|
||||
public record Pop(int node, int count) {
|
||||
|
||||
}
|
||||
public record Give(int donor, int dest, int c) {
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,9 @@ import nu.marginalia.actor.prototype.AbstractActorPrototype;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static nu.marginalia.control.actor.rebalance.RebalanceActor.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
class RebalanceActorTest {
|
||||
@ -15,18 +14,26 @@ class RebalanceActorTest {
|
||||
|
||||
@Test
|
||||
void calculateTransactions1_2() {
|
||||
var transactions = actor.calculateTransactions(Map.of(1, 100, 2, 0));
|
||||
var expected = List.of(new RebalanceActor.Give(1, 2, 50));
|
||||
var transactions = actor.calculateTransactions(
|
||||
List.of(new Pop(1, 100), new Pop(2, 0))
|
||||
);
|
||||
var expected = List.of(new Give(1, 2, 50));
|
||||
|
||||
Assertions.assertEquals(expected, transactions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void calculateTransactions1_3() {
|
||||
var transactions = actor.calculateTransactions(Map.of(1, 90, 2, 0, 3, 0));
|
||||
var transactions = actor.calculateTransactions(
|
||||
List.of(
|
||||
new Pop(1, 90),
|
||||
new Pop(2, 0),
|
||||
new Pop(3, 0)
|
||||
)
|
||||
);
|
||||
var expected = List.of(
|
||||
new RebalanceActor.Give(1, 2, 30),
|
||||
new RebalanceActor.Give(1, 3, 30)
|
||||
new Give(1, 2, 30),
|
||||
new Give(1, 3, 30)
|
||||
);
|
||||
|
||||
Assertions.assertEquals(expected, transactions);
|
||||
@ -34,10 +41,16 @@ class RebalanceActorTest {
|
||||
|
||||
@Test
|
||||
void calculateTransactions2_3() {
|
||||
var transactions = actor.calculateTransactions(Map.of(1, 30, 2, 30, 3, 0));
|
||||
var transactions = actor.calculateTransactions(
|
||||
List.of(
|
||||
new Pop(1, 30),
|
||||
new Pop(2, 30),
|
||||
new Pop(3, 0)
|
||||
)
|
||||
);
|
||||
var expected = List.of(
|
||||
new RebalanceActor.Give(1, 3, 10),
|
||||
new RebalanceActor.Give(2, 3, 10)
|
||||
new Give(1, 3, 10),
|
||||
new Give(2, 3, 10)
|
||||
);
|
||||
|
||||
Assertions.assertEquals(expected, transactions);
|
||||
@ -46,7 +59,7 @@ class RebalanceActorTest {
|
||||
@Test
|
||||
void calculateTransactionsEmpty() {
|
||||
try {
|
||||
actor.calculateTransactions(Map.of());
|
||||
actor.calculateTransactions(List.of());
|
||||
Assertions.fail("Expected transition");
|
||||
}
|
||||
catch (AbstractActorPrototype.ControlFlowException ex) {
|
||||
@ -54,11 +67,12 @@ class RebalanceActorTest {
|
||||
}
|
||||
|
||||
try {
|
||||
actor.calculateTransactions(Map.of(1, 100));
|
||||
actor.calculateTransactions(List.of(new Pop(1, 100)));
|
||||
Assertions.fail("Expected transition");
|
||||
}
|
||||
catch (AbstractActorPrototype.ControlFlowException ex) {
|
||||
Assertions.assertEquals("END", ex.getState());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user