powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Подсчет числа событий в момент времени
11 сообщений из 11, страница 1 из 1
Подсчет числа событий в момент времени
    #39711564
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, что задача не настолько тривиальна, как может показаться.
Стоит задача написать примитивный сервис, который будет считать рейт событий.

Событие будет его вызывать и увеличивать счетчик.
Код: java
1.
rateService.inc("event-name");



Потом в другом месте нужно получить данные, какая скорость событий (события в секунду).
Код: java
1.
rateService.get("event-name");



Идей, конечно, много. Но не хотелось бы городить городушки.
Самое простое, как мне видится хранить в следующем виде:

Код: java
1.
HashMap<String>, List<AtomicLong>>


где String - имя события
ключ списка - секунда (от 0 до 59) в которую происходит событие
ну и значение списка - это число событий

По сути лист будет записываться по кругу, только вот вопрос с обнулением, где и как это делать при конкурентном доступе.

Может есть способ лучше?
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711566
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
HashMap<String>, List<AtomicLong>>


Этот способ мне кажется перспективным, так как можно получать число событий в секунду (выдаем всегда предыдущую, так как текущая заполняется в данный момент времени), число событий в минуту (сумма всех событий). Можно адаптировать и к другим интервалам.

А может есть либа какая уже готовая?
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711581
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hett
Код: java
1.
HashMap<String>, List<AtomicLong>>




Это в принципе работать не будет, без внешней синхронизации. И ConcurrentHashMap взять тоже нельзя, потому что там read всего лишь eventually-consistent.

Непонятно сколько ивентов ожидается, сколько нод, как они будут синхронизированы. Если одна нода и ивентов не дикое количество, то может тупо synchronized или ReadWriteLock? Прежде чем наворачивать, надо бы померять на реальной нагрузке
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711681
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Одна нода и точность подсчета не критична.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
package status;


import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class RateCounterService {

    private final int capacity;
    private Map<String, List<AtomicInteger>> stats = new ConcurrentHashMap<>();
    private volatile long currentTimestamp = Instant.now().getEpochSecond();
    private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    public RateCounterService(int capacity) {
        this.capacity = capacity;
        executorService.scheduleAtFixedRate(() -> {
            currentTimestamp = Instant.now().getEpochSecond();
            int index = getIndex(0);
            for (Map.Entry<String, List<AtomicInteger>> entry : stats.entrySet()) {
                stats.get(entry.getKey()).get(index).set(0);
            }
        }, 1, 1, TimeUnit.SECONDS);
    }

    public void inc(String statName) {
        int index = getIndex(0);
        stats.computeIfAbsent(statName, k -> {
            List<AtomicInteger> list = new ArrayList<>(capacity);
            for (int i = 0; i < capacity; i++) {
                list.add(i, new AtomicInteger(0));
            }
            return list;
        });
        stats.get(statName).get(index).incrementAndGet();
    }

    /**
     * @param statName any string key
     * @return amount of events, measured in the previous time unit (the current is still filling)
     */
    public Integer get(String statName) {
        int index = getIndex(-1);
        return stats.get(statName).get(index).get();
    }

    public long getTotal(String statName, int units) throws RateCounterException {
        long total = 0L;
        if (units < 0) {
            throw new RateCounterException("units can be greater than 0");
        }
        if (units > capacity) {
            throw new RateCounterException("units can not be greater than `capacity`");
        }
        List<AtomicInteger> list = stats.get(statName);
        for (int i = units; i > 0; i--) {
            int index = getIndex(-i - 1);
            total += list.get(index).get();
        }
        return total;
    }

    private int getIndex(int correction) {
        return (int) ((currentTimestamp + correction) % capacity);
    }

}



Как-то так получилось.
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711757
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имхо переусложнено, да и не совсем правильно, если уж на то пошло. Но, если авторточность подсчета не критична. то в принципе работать будет.

Что мне здесь не нравится -

1) В конструкторе стартовать потоки это моветон, в вашем случае все будет ок, но вообще возможна ситуация, когда поток заснет до выхода из конструктора, а ваш шедулер запустится на выполнение над недоинициализированным объектом
2) Вы наивно полагаете, что код executorService.scheduleAtFixedRate(() -> (), 1, 1, TimeUnit.SECONDS); будет вызываться наносекунда в наносекунду? Твкую точность никто не гарантирует - так что идем к 3)
3) Я бы кажому ивенту ассайнил бы таймстамп, и складывал бы их один за одним в некую структуру данных, другой поток в оффлайне уже бы разбивал их на секунды и т.д Без всяких атомиков и т.п усложнений.

Вообще много чего можно сказать, конечно, но я пожалуй закруглюсь
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711902
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. А как делать? Вызывать его инициализацию дергая отдельный метод?
2. Тут не те требования, чтобы прям до микро/нано секунд. Еще вроде возможна ситуация когда таймер будет обнулять счетчик, а этот счетчик еще будет выдаваться, потом только это понял.
3. Да, ваш способ проще и лучше. Я чет не догадался так, завтра может переделаю, если будет не лень.

А что еще?

Кстати не первый раз с таким сталкиваюсь, что из некоторых методов проще вернуть скалярный тип данных (чтобы не делать лишний боксинг), а где-то работаешь с объектным и возвращаешь его. На сколько это адекватно, что разные методы возвращают данные типы (где-то объект, где-то скаляр)?
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711923
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hett1. А как делать? Вызывать его инициализацию дергая отдельный метод?
Да, часто делают метод init() с такой логикой. А вместе где вызывается конструктор сначала делается new Object(); obj.init() Но это имеет минус конечно, логика размазанная и кто-то может забыть init(), зато потокобезопасно, тут каждый выбирает для себя.
Hett2. Тут не те требования, чтобы прям до микро/нано секунд. Еще вроде возможна ситуация когда таймер будет обнулять счетчик, а этот счетчик еще будет выдаваться, потом только это понял.
Да, именно так

HettА что еще?

Кстати не первый раз с таким сталкиваюсь, что из некоторых методов проще вернуть скалярный тип данных (чтобы не делать лишний боксинг), а где-то работаешь с объектным и возвращаешь его. На сколько это адекватно, что разные методы возвращают данные типы (где-то объект, где-то скаляр)?
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39711926
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
случайно отправилось.
авторА что еще?
Да по-большому счету все, остальное - это уже из-за того что у вас архитектура навороченная, есть некоторые моменты но о них писать нет смысла, ибо если переделаете они уйдут.
автор На сколько это адекватно, что разные методы возвращают данные типы (где-то объект, где-то скаляр)?
Ну для обычной разработки некритично, но вообще это проблема, да. В высоконагруженных приложениях может выстрелить. Я сейчас на Scala, там такой проблемы особо нету, но если пишу на Java я по дефолту всегда ставлю int
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39712105
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже на Meters
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39712208
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixxer,

похоже, спасибо!
...
Рейтинг: 0 / 0
Подсчет числа событий в момент времени
    #39712499
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
заюзал либу в общем.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Подсчет числа событий в момент времени
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]