Discussion in 'Plugin Development' started by chaseoes, Aug 4, 2012.

Thread Status:
Not open for further replies.
  1. chaseoes
    So I guess they basically run the new chat event in a different thread other than the main thread to improve performance. They used a queuing list to maintain the order of the messages being sent and in addition, added a method similar to setPlayer() in a CommandPreProcessEvent (the event triggered before a command is executed) to change the player who is performing the command. They also mentioned that the previous Chat Event was going to be removed soon so they want developers to switch over as soon as possible to 1.3.

    Also, I just wanted to see what would happen if the message were translated 50 times:
    Code (Text):
    1. The addition of two tools to use to ensure lazy to PlaierChatEvents
    2. Training activities and, in parallel with the needs of players
    3. List.
    5. If the system is waiting for the hidden reason is similar to the third session. if
    6. Plug-in listen PlaierChatEvent to date, all incoming calls
    7. The delay reflects the mainstream. All programmers
    8. Recommended the development of the API in an interview with journalists bukkit
    9. Minimum frequency shift from server stability.
    11. In addition, changes in road safety issues must
    12. Logic. Production CopiOnVriteArraiList son is the only viable
    13. And responsible for the normal range of the security
    14. Some need the logic processing system network management.
    16. For small changes, it is expected that executive function
    17. PlaierCommandPreProcessEvent. Install the player now has to change
    18. The tasks of the players.
    Please excuse my randomness. :)
  2. Basically in order to reduce server lag the new chat system runs in a separate thread (yay threads)
    But in order to maintain compatibility with old plugins, Bukkit has to join these two threads. This reduces performance. So to prevent this from happening plugin devs have been told to listen to these events from the get go so Bukkit doesn;t have to join these threads, the downside is you might land up with something accessing the same thing at the same time, something that must be guarded against.
  3. So is there any difference between them that affects plugins? Do chat plugin authors simply have to change the name of the event they listen to?
  4. They also need to ensure thread safety.
  5. Offline


    Can you go into more detail? How am I supposed to run some logic that requires anything hinging on bukkit API and still be able to cancel the event?
  6. Now when my server frozen, everything stops working but the chat don't :D
  7. Schedule a sync task
  8. So... only thread safe methods? :\

    right! didnt read the latest message.
  9. Thread safe methods are also alright, however depending on what you need to do, chances are you may need to use more methods than the thread safe ones.

    and player.sendMessage(message) are pretty much the core thread safe methods. There are also bound to be a few more, there is an incomplete list on the wiki:
  10. I can sort of see an incoming flood of confused beginners and even more plugins with threading issues with that new event.
    So far, having to have the own plugin multi-threaded was pretty uncommon, and beginners who don't know much about that topic could leave their hands off of it. But now, they are kind of forced to include that other thread if they want to hook chat events. Many probably don't even care and simply use it like any other event - creating even more time-bombs spreading around servers.

    I suppose most of the time when you use the chat event, you need to get information from your own plugin. That means that now you have to synchronize this information correctly, which I assume not many developers know how to do.

    It's not only about unsafe bukkit API methods now, but about unsafe internal structures of the plugin which have to be secured since there's no other way if you have to use the listener to modify the event.

    Of course, if all you need to do is process what the player typed and do something else with it, it's relatively easy to get that back into the main thread, but that won't allow you to modify the event (with the desired effects).

    Oh well, I suppose we will have to live with that. Maybe someone gets around to writing a guide on how to handle that properly (in other words: explain concurrency).
  11. Md, I'm new to server stuff so hopefully you can help me with my problem.

    So basicly, People join my server but they cant break blocks. Only Ops can. Please help!
  12. Completely wrong thread/forum. Way off topic.
    kroltan likes this.
  13. Sorry I'm new :p
  14. Permission checks are not thread safe, you'll need to completely re-write how you handle the chat event so that it runs in the main thread, ie use the scheduler to process everything and cancel the chat. Configuration changes are also not thread-safe. Yes it's dumb since it basically means chat is handled identically to 1.2.5 and completely ruins inter-plugin communication/handling of the chat. No bukkit doesn't seem to care.

    md_5 if you have any other alternatives to this I'm open for suggestions.
    ZachBora likes this.
  15. :/ that sucks chat not working in crash is useful as then Ik it's crashed. I don't want crash and people going "omg what's happening, I can't move" and spam for an enevitible crash ;(
  16. Offline

    Sagacious_Zed Bukkit Docs

    That is not the only way to handle it. There are other options, which still let you do some processing possibly on the async thread. Such as writing to your own cache the information you need to compute other information.
  17. Not to undermine the knowledge of the dev team, But can i get some insight as to how having synced chat events was lagging the server?

    Cuz now with cancelling the async chat event then scheduling a sync runnable.... well.. that seems kinda unfair to the plugins that get the event AFTER the first plugin to do this.
  18. Offline

    mbaxter ʇıʞʞnq ɐ sɐɥ ı Retired Staff

    Sync'd chat events lag chat noticeably compared to when no plugin is listening to sync'd chat. It's not huge, but it's there.

    Why would you cancel the async and schedule a sync runnable, that's not a good solution.
  19. I'm a pretty advanced programmer, I help the beginners out here on the plugin development forum quite a lot, and *I* don't understand how to properly develop my plugins for 1.3 using AsyncPlayerChatEvent or what the implications are of various choices.

    Not saying that I won't figure it out. Just saying that I find myself answering noob questions here all the time, and this new thing has the potential to be a major pain in the ass to people trying to learn, until/unless and concise yet comprehensive guide comes out explaining the implications.
    Bone008 likes this.
  20. apologies. I figured thats what i was being told to do. 6_9
  21. OK, trying to understand this. Take my ScrollingMenuSign plugin as an example. One of the things you can do with it is set up "prompted" commands, where the player clicks a menu entry, gets prompted by the game to enter some text, and then the command is run with the entered text substituted into it. I used the PlayerChatEvent for that - checking if the plugin was expecting some input from the player, and if so, running the menu command with the text substituted (and cancelling the event). All well and good.

    Now, with the AsyncPlayerChatEvent, the event handler is running in a different thread (I presume it's guaranteed to always be in a different thread - so far, Thread.currentThread().getId() returns a different thread id for the chat handler and the main thread).

    So, what can I actually do here? I think I can do my plugin-specific checks in the separate thread (that's basically looking the player up in a HashMap to see if there's a response being expected, and building the substituted command string - all pretty thread-safe), but then I will need to schedule a sync delayed task to actually execute the command. Right?
  22. Offline

    Sagacious_Zed Bukkit Docs

    In the JavaDoc it mentions that it can sometimes be on the main thread. You can check the returned value from isAsynchronous() and plan accordingly.

    Normal HashMap lookups are also not thread safe. ConcurrentHashMap maybe the right choice here. But then yes, if you need the affect the game in some way the logic needs to be be placed in a task.
  23. Use CommandPreProcessEvent?
  24. I thought that event was only fired for commands (i.e. something starting with "/")? I need to intercept when the player types anything.

    Edit: yes, it's only called for commands, not general player chat. See handleCommand() in net.minecraft.server.NetServerHandler.
  25. Because at the moment there is absolutely no other alternative other than blocking the netserverhandler thread on the player. You can't perform any permission checks at the moment anyway due to non-thread-safe methods. Again, if you have a solution that doesn't block the main thread or the NSH and still allows permission/config checks or command processing on triggered chat, we're waiting..

    desht - yes, the only time it wont be async is when another plugin fires the chat event due to some triggered plugin that's running on the main thread, or from a command.
  26. From what I understand you don't need to modify the chat in that thing you're doing. So just create a Callable class. It's what I did on one of my plugins.

    The only people that should have a problem with the Async event is people that need to modify the message using permission/config/etc.

    Code (Text):
    2. public void onPlayerChat(final AsyncPlayerChatEvent event)
    3. {
    4.   Player player = event.getPlayer();
    6.   if(event.isAsynchronous())
    7.   plugin.getServer().getScheduler().callSyncMethod(plugin, new CallableAddPlayerToList(player, plugin));
    8.   else
    9.   plugin.addPlayerToList(player);
    10. }
    12. public class CallableAddPlayerToList implements Callable<Object>
    13. {
    14. private Player player;
    15. private iChatPlayerList plugin;
    17. CallableAddPlayerToList(Player p, iChatPlayerList pl)
    18. {
    19.   player = p;
    20.   plugin = pl;
    21. }
    23. @Override
    24. public Object call() throws Exception {
    25.   plugin.addPlayerToList(player);
    26.   return null;
    27. }
    28. }
  27. I'm not sure there's any benefit to using callSyncMethod() here if you're just throwing the return value away, since callSyncMethod() is just a wrapper around scheduleSyncDelayedTask() using a Future/Runnable combination (CraftFuture) to capture the task's return value. You might as well just use scheduleSyncDelayedTask().

    I'm with Sleaker (and others, go look up the github commit for this) on this one - it's a mess, and pretty much certain to lead to a mass of subtle and not-so-subtle server errors as plugin authors just change their PlayerChatEvent handlers to AsyncPlayerChatEvent and not consider the consequences of that. Bukkit/CraftBukkit simply isn't set up to handle a proper multi-threaded environment and bolting this on with minimal communication to plugin developers really is asking for trouble. And not helped by the Big Scary Warning that CB 1.3.1 emits when plugins register for the old PlayerChatEvent.
    Bone008 and CorrieKay like this.
  28. you just described nearly every chat plugin.
    ferrybig, tyzoid and russjr08 like this.
Thread Status:
Not open for further replies.

Share This Page