Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем DPOH-VAR, 5 сен 2012.

  1. Автор темы
    DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    Итак, имеются два разных эвента:
    PlayerChatEvent и AsyncPlayerChatEvent
    разница между ними в том, что второй запускается асинхронно, даже если сервер повис.
    В документации bukkit сказано, что на AsyncPlayerChatEvent накладываются ограничения в использовании, а бывший класс PlayerChatEvent отмечен как устаревший.
    Вот наглядная разница между ними:
    Например, нужно передать эвент на обработку в другой поток, который может отменить его (.setCancelled()) или как-либо изменить:
    Код:
    @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, вносить в него изменения, или же пропустить.
     
    D_ART, fromgate и ufes нравится это.
  2. Хостинг MineCraft
    <

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