Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Асинхронные эвенты

DPOH-VAR

Старожил
Пользователь
Баллы
153
Итак, имеются два разных эвента:
PlayerChatEvent и AsyncPlayerChatEvent
разница между ними в том, что второй запускается асинхронно, даже если сервер повис.
В документации bukkit сказано, что на AsyncPlayerChatEvent накладываются ограничения в использовании, а бывший класс PlayerChatEvent отмечен как устаревший.
Вот наглядная разница между ними:
Например, нужно передать эвент на обработку в другой поток, который может отменить его (.setCancelled()) или как-либо изменить:
Java:
@EventHandler public void action(PlayerChatEvent event){
        task.run(event); //отправляем эвент на обработку в другой процесс
        synchronized (event){
            try {
                event.wait(); // ждем отклика из другого потока
            } catch (InterruptedException e) {
                System.out.print("ошибка InterruptedException");
            }
        }
    // завершение обработки эвента
    }
task - объект, содержащий метод для обработки эвента в отдельном потоке.

Вот что произойдет вызове обычного PlayerChatEvent:
  • игрок пишет в чат сообщение.
  • создается новый поток в функции task.run(...)
  • сервер повисает.
  • поток, инициализированный в task.run(...) обрабатывает эвент (это может происходить сколько угодно долго, например при работе с БД и сокетами)
  • затем этот поток отправляет отклик event.notify()
  • хандлер action() завершает свою работу
  • bukkit обрабатывает объект event
  • сервер отвисает

Если же заменить PlayerChatEvent на AsyncPlayerChatEvent:
  • игрок пишет в чат сообщение.
  • создается новый поток в функции task.run(...)
  • сервер не повисает.
  • происходит ошибка InterruptedException
  • хандлер action() завершает свою работу
  • bukkit обрабатывает объект event (по сути в нем ничего не изменилось)
  • поток, инициализированный в task.run(...) обрабатывает эвент, но все это впустую.
Итог:
на AsyncPlayerChatEvent накладываются ограничения, не позволяющие потоку обработчика задерживать выполнение. Это хорошо, например, если какая-то команда повесила сервер, а второй командой можно ее отменить.
Знаю, что задерживать выполнение обработчика крайне нежелательно, тем более отправлять в параллельный поток, однако в моем случае это необходимо. Другой поток должен решать, нужно ли отменять event, вносить в него изменения, или же пропустить.
 

Поделиться этой страницей

Назад
Верх