Solved Running Heavy Task

Discussion in 'Spigot Plugin Development' started by WAS, May 17, 2017.

  1. WAS


    I'm curious. If I were to be running a heavy task that performs a lot of stuff outside the Minecraft Server, such as manipulating the OS file system. How would I go about doing that task, and when it's complete sending the player the response produced by the task. I notice async tasks should not access the API, I assume this includes sending a user a message.

    Can someone direct me how I could perform any sort of heavy computation/scripts and get their response (which would take time)?
    #1 WAS, May 17, 2017
    Last edited: May 17, 2017
  2. Do not run them in the Main thread. Never. Create at least one new Thread. For the best performance split the one Thread into multiple Threads and then complete on after another.
  3. This sounds like a great reason to use TaskChain, it was created for this exact purpose.
  4. WAS


    Granted. I hope you read the topic. This is about getting a response back from this task on other threads haha.

    Oooh, yet another great one by Aikar. Going to look at this. Ohh TaskCain, I remember this. Not sure why I didn't remember it.

    For the sake of others, and vanilla spigot/bukkit flavor, I'll keep this open for other methods.


    Create a Bukkit Task class. This class has a simple hash map. UUID -> String (Response). The async tasks injects this Bukkit task with a UUID and Response, which than the already task finds there is a entry, sends it to the player, and removes it.
    #4 WAS, May 17, 2017
    Last edited: May 17, 2017
  5. TaskChain works for Vanilla Bukkit, pretty much every version in past 4 years.

    very little API touching.
  6. Well, you can still interact with the scheduler, therefore you can just execute a Scheduler.runTask() to execute something back on the main thread when you're done.
    • Like Like x 1
  7. This is ultimately what TaskChain does, but in a more clean API.

    You define what "thread" to run it on with sync and async keywords, and as the chain executes, it will switch threads before running the next step in the chain to ensure your on the right thread, calling the bukkit scheduler methods.

    TaskChain was designed super abstract so it actually supports more than just Bukkit :) ANY Game Server with a scheduler can use it.
    • Like Like x 1
  8. WAS


    Seems pretty much like my idea but spawning an anonymous within the async task.
  9. WAS


    Fairly certain it's expressed in various places to use Bukkit tasks, and not Java's. I feel like that's why we have the Async method.

    Is establishing a new BukkitRunnable() inside a async one considered "using the API", is that sane?
    #9 WAS, May 17, 2017
    Last edited: May 17, 2017
  10. the BukkitScheduler is one of the few parts of the API that's thread safe. I wouldn't use BukkitRunnables just to hop back to the main thread though, just use BukkitScheduler::runTask(Plugin, Runnable) (or use TC's own method if you're using it)
    • Like Like x 1
  11. WAS


    I'm not sure I've used the scheduler (I thought most of it was deprecated or something?). Could that be done like:

    Code (Java):
    Runnable task = new Runnable() {
               public void run() {
                         // Response  

    Bukkit.getScheduler().runTask(plugin, task);
  12. If it's a really heavy task, i'd use the async tasks instead.

    Code (Text):
    Bukkit.getScheduler().runTaskAsynchronously(MAIN, new Runnable(){
        public void run(){
            // do shit
  13. WAS


    -__- xD

    It is. This is the response, back on the main thread, to use the API.
  14. Yup, that's how you do it. The deprecation was for the methods which accept BukkitRunnable (since those should be scheduled using the methods in BukkitRunnable instead), and for the methods which had some confusing naming (scheduleASyncTask or scheduleAsyncTask, shouldn't be too hard to realise why that was deprecated, lol)
    • Like Like x 1
  15. WAS


    Oohh ok. That makes perfect sense now.