Asynchronous and synchronous - What to use

Discussion in 'Spigot Plugin Development' started by rickydaan, Jun 15, 2015.

  1. Hello, Spigot

    I am dealing with an issue right here. I have been working on a system that involves many entities (A minigame). There's a timer that runs a task every tick, and in that task another function is being called to remove the animal after a certain amount of ticks. Here is some visualization:

    Code (Text):

        // final Entity e //
        Bukkit.getScheduler().runTaskTimerAsynchronously(Minigames.getInstance(), new Runnable(){
           @Override
           public void run(){
             MinigamesUtils.handle(e);
           }
         }, 0L, 1L);
    Code (Text):

    public static void handle(final Entity e){
         // Handle the entity here...
         Bukkit.getScheduler().runTaskLaterAsynchronously(Minigames.getInstance(), new Runnable(){
           @Override
           public void run(){
             e.remove();
           }
         }, 1L);
       }
    Now obviousely entity management can not be done asynchronously, but how would I go with performing the proper actions? What should I do?
    Running this on the main thread would certainly do have an impact on the server's performance, which is the last thing I want.

    Thank you in advance!
     
    • Optimistic Optimistic x 1
  2. Everything you do on the main thread, (and arguably on other threads as well) no matter what it is, has some sort of an impact on the server performance. If you need to run actions that need to be run on the main thread, such as entity management, then you really have no choice but to run them on the main thread. I.e not asynchronously.

    Did that clear things up for you?
     
    • Like Like x 1
  3. It sure did, but in the end we are talking about possibly 2000 entities per tick, which is not what I believe should be done on the main thread. The main question was if there was an alternative thread-safe method of doing so. I guess not, unfortunately. Most posts about this I found out are alot older than now, so that's what I wondered :) Thank you for your help ;)
     
    • Like Like x 1
  4. 2000 entities per tick doesn't sound like much. Have you tried this? Run some benchmarks.
     
    • Like Like x 1
    • Useful Useful x 1
  5. Will do :) Thanks for the information ;)
     
    • Like Like x 1
  6. You use sync if you use Bukkit API(Some exception such as sendmessage , sendblockupdate etc...) , async if you think its a heavy operation that does not require bukkit , simple as that
     
    • Like Like x 1
  7. Yeah, I know and knew that already. The main question was if there was a way to do it somewhere else rather than on the main thread.
     
    • Like Like x 1
  8. Oh i miss read it, and to answer your question, no (unless you want to start modding craftbukkit and deal with all the multi thread issue)

    and even if you try you would be likely caught by

    https://hub.spigotmc.org/stash/proj...t-Patches/0009-Async-Operation-Catching.patch

    However you are not doomed

    Your main concern is performace rather than not wanting to do it on main thread

    so you can queue entities for removal and allow up to about 100? entity remove per 5 ticks, process others in the next 5 tick
     
    • Like Like x 1
  9. Nah, to not reveal the project I am working on (The person I am working for restricts me to share the least bit of information) I had to disguise some of the functions. The main point is that later on there might be 2000 to 10000 entities being updated every tick to two ticks, which would be a pain...
     
    • Like Like x 1
  10. Update half the entities on one tick and the other half on the next. Spread out your computation.
     
    • Like Like x 1
  11. Its based on the things you have to compute.
    If computations takes much time (per entity), run that async (depending on your cpu you could create up to cpu thread amount threads theoretically) and then run a sync tasks with the results. If the computation does not last long, the overhead of moving that to an async thread is more than your computations last.
     
    • Like Like x 1
  12. Perhaps if you're not able to complete the task for a job, you shouldn't agree to take on jobs that require you to not share information.

    Async tasks merely operate a runnable in a thread pool, seperate from bukkit's main thread. You should use thread-safe operations while asynchronous, and avoid methods in org.bukkit.* (or at least investigate the ones you do use for thread safety).

    Threading your plugin/program isn't as simple as just switching "sync" to "async", there are race conditions and states which you must consider.
     
  13. If you want to start new threads off the main thread, that is a code design decision that is fairly advanced. Your plugin doesn't sound super heavy weight, my conclusion is stick with the method that is will cause the least issue in the future.
     
    • Like Like x 1
  14. The interesting question is, why do you have to compute all these things every tick? Even if you would still schedule the task every second tick (only 0.05s later) you'd only have to compute half the entities.
     
    • Like Like x 1
  15. Yes, but there are possible complications with partial processing for the novice Java programmer.
     
    • Agree Agree x 1
  16. Could you elaborate:confused:?
     
  17. He is trying to tell that in his opininon there are alot of novice programmers that would not be able to spread out the load per tick (eg instead of dealing with 50K caluclations each 2 ticks, dealing with 25K calculations each tick)
     
    • Agree Agree x 1
  18. runTaskLater is better