diff --git a/noiser/build.gradle b/noiser/build.gradle new file mode 100644 index 0000000..0efd63f --- /dev/null +++ b/noiser/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'java' +} + +group = 'ru.dragonestia' +version = 'unspecified' + +repositories { + mavenCentral() +} + +dependencies { + implementation project(":client-api") + implementation project(":client-impl") + + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/noiser/src/main/java/ru/dragonestia/picker/noiser/Main.java b/noiser/src/main/java/ru/dragonestia/picker/noiser/Main.java new file mode 100644 index 0000000..256172f --- /dev/null +++ b/noiser/src/main/java/ru/dragonestia/picker/noiser/Main.java @@ -0,0 +1,127 @@ +package ru.dragonestia.picker.noiser; + +import ru.dragonestia.picker.api.impl.RoomPickerClient; +import ru.dragonestia.picker.api.model.node.NodeDefinition; +import ru.dragonestia.picker.api.model.node.PickingMethod; +import ru.dragonestia.picker.api.model.room.RoomDefinition; +import ru.dragonestia.picker.api.repository.query.node.GetAllNodes; +import ru.dragonestia.picker.api.repository.query.user.UnlinkUsersFromRoom; +import ru.dragonestia.picker.api.repository.type.NodeIdentifier; +import ru.dragonestia.picker.api.repository.type.RoomIdentifier; +import ru.dragonestia.picker.api.repository.type.UserIdentifier; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + + +public class Main { + + private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(8); + private final Random random = new Random(); + private final RoomPickerClient client; + private final List nodes; + + private final Map totalUsers = new ConcurrentHashMap<>(); + private final int expectedUsers = 10000; + + public Main() { + client = new RoomPickerClient("http://localhost:8080", "admin", "qwerty123"); + nodes = initNodes(); + } + + private void removeAll() { + client.getNodeRepository().allNodes(GetAllNodes.JUST) + .forEach(node -> client.getNodeRepository().removeNode(node)); + } + + private List initNodes() { + removeAll(); + + var list = new ArrayList(); + + for (int i = 0; i < 5; i++) { + var node = new NodeDefinition(NodeIdentifier.of("test-node-" + i)) + .setPickingMethod(PickingMethod.values()[i % PickingMethod.values().length]); + + client.getNodeRepository().saveNode(node); + + var nodeId = node.getIdentifierObject(); + totalUsers.put(nodeId, new AtomicInteger(0)); + list.add(nodeId); + } + + return list; + } + + private void initRooms() { + final int perNode = expectedUsers / nodes.size(); + final int roomsPerNode = perNode / 10; + + for (var nodeId: nodes) { + for (int i = 0; i < roomsPerNode; i++) { + client.getRoomRepository().saveRoom( + new RoomDefinition(nodeId, RoomIdentifier.of(UUID.randomUUID().toString())).setMaxSlots(roomsPerNode) + ); + } + } + } + + private void pickUsers() { + for (var nodeId: nodes) { + var usersInNode = totalUsers.get(nodeId); + + try { + synchronized (usersInNode) { + var users = new HashSet(); + var maxAdd = Math.min(10, (expectedUsers / nodes.size()) - usersInNode.get()); + + if (maxAdd == 0) return; + var add = maxAdd == 1 ? 1 : (random.nextInt(maxAdd - 1) + 1); + for (int i = 0; i < add; i++) { + users.add(UserIdentifier.of(UUID.randomUUID().toString())); + } + + var request = client.getNodeRepository().pickRoom(nodeId, users); + usersInNode.addAndGet(add); + var roomId = RoomIdentifier.of(request.roomId()); + + System.out.printf("Added %s(total %s) users to %s/%s%n", add, usersInNode.get(), nodeId.getValue(), roomId.getValue()); + + scheduler.schedule(() -> { + try { + client.getUserRepository().unlinkUsersFromRoom(UnlinkUsersFromRoom.builder() + .setNodeId(nodeId) + .setRoomId(roomId) + .setUsers(users) + .build()); + + usersInNode.addAndGet(-add); + System.out.printf("Reduced %s users from %s/%s%n", add, nodeId.getValue(), roomId.getValue()); + } catch (Exception ex) { + System.out.println("Error(" + ex.getClass().getSimpleName() + "): " + ex.getMessage()); + } + }, random.nextInt(1000) + 100, TimeUnit.MILLISECONDS); + } + } catch (Exception ex) { + System.out.println("Error(" + ex.getClass().getSimpleName() + "): " + ex.getMessage()); + } + } + } + + public void startNoise() throws InterruptedException { + initRooms(); + + while (true) { + pickUsers(); + Thread.sleep(10); + } + } + + public static void main(String[] args) throws InterruptedException { + new Main().startNoise(); + } +} \ No newline at end of file