Long delayed tasks (save/load Tasks/Threads)

Discussion in 'Plugin Development' started by IDragonfire, Sep 12, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    IDragonfire

    Hello Devs,
    is there any Timer Library for schedule/save/load long delayed tasks?

    The problem is, that I have many calls that must be execute in the future (1day, 3days, ....) and in different Plugins ...

    I am afraid to create a delayed Thread for each Task.
    Also I must catch if the server stopped/reloded and save the Threads/Runnable object or implement another save mechanism. (It is difficult to save a Thread object, that the reason why it isn't serializable)

    If no Library exist, I have the following draft:

    A new Scheduler (DScheduler) with a registerListener(Plugin, DTimerListener) and scheduleEvent(Plugin, DTimingEvent)

    A DTimerListener with onDTimerEvent(DTimingEvent) and maybe onDLoadException(Exception)

    A DTimingEvent with save(), load(), isAsync(), getExecutionTime(), getName()

    You must register a DTimerListener, call the scheduleEvent method from the DScheduler with your own extended DTimingEvent ...
    The scheduler makes a decision, maybe he saves the DTimingEvent on Disk/DB/... (because execution is in one month) or cache it into RAM...
    The DScheduler has ONE main thread, maybe based on:
    https://gist.github.com/2821924
    and creates Sync or Asyn Threads that call the event at the ececution time with the given DTimingEvent.

    Advantage
    • Bukkit has less Threads to managed ...
    • An automatic save meachism (with a DSerialziableTimingEvent that implements Serialzable)
    • Admin commands like /remainingTime <TimingEventName>

    Disadvantage
    • Bukkit lose control over some ThreadHandling
    • You must trust the DScheduler
    • Don't know if Bukkit lower the priority if I call often the Bukkit scheduler method from DScheduler
     
  2. Offline

    andf54

    How about you save System.currentTimeMillis() to disk (to restore after /reload) and check every minute/hour how much days have passed.
     
  3. Offline

    IDragonfire

    I did not talk about how the DScheduler check the time ... (scheduling the Threads/Tasks)
    For me it is important to store and restore the data for execution automaticly ...
     
  4. Offline

    andf54

    Can you just enable scheduler for every plugin when onEnable is called?
     
  5. Offline

    IDragonfire

    Last edited by a moderator: May 28, 2016
  6. Offline

    Milkywayz

    You just gave me a good idea! :D
     
  7. Offline

    IDragonfire

  8. What's wrong with bukkits scheduler? In the newest version of EndReset I am able to start, stop, suspend and restart tasks. To do this I save the time (in ticks) when the task starts and to suspend it I calculate the remaining ticks and save it together with other important info (in that case only the worlds name) in a HashMap<WorldName, RemainingDelay>. The WorldName is a string and the RemainingDelay a long, so it's perfectly serializable.

    BTW: A serializable task object is somehow impossible as a task always includes runnable which isn't serializable. Also you may want to have a reference to your plugin in your task, but your plugin extends JavaPlugin which isn't serializable, too...
     
  9. Offline

    IDragonfire

    That is the problem ...
    Every plugin author must writes his own methods to save/load the HashMap/Thread info ...
    That the reason I use my own DataContainer, called DTimer (it can be serializable).
    Also it is impossible to schedule tasks at a specified realtime (like 24.12.2012 12am) with one method call,
    or is there an easier way?
     
  10. IDragonfire Yes, you are right, every plugin that wants to extend bukkits scheduler (like EndReset does for suspending) needs its own methods for that, but all in all such a small HashMap will be lightweighter than your DTimer (serializes needed data only and the whole logic has around 20 lines). Also the tasks can still contain a reference to the plugins instance and other not serializable data.
    Also you are right with real-time scheduling. But I see a problem there, too: You can't ensure that the server is running while the task should be executed. It has a reason the scheduler depends on in-game time. ;)
     
  11. Offline

    IDragonfire

    Serialziable is only one way, you can also implement your own method ...
    That the task should execute when the server is not running is one reason I started these project.
    I want to trigger a event is the execution time passed ...
    My scheduler is only a layer between BukkitScheduler and plugins ...
    But I take a closer look at EndRest ...
    Did you take a closer look to my code?

    Edit:

    EndRest is not openSource :(

    Summary:
    I have a huge number of tasks that must be called in a future from different plugins ...
    I must store these calls (server restart/shutdown)
    It is a bad idea to create for all plugins and Tasks a delayed Thread (if the server lags, <20TPS the execution time is inexact)
     
  12. IDragonfire feel free to look at EndReset even if your code isn't GPLed, too, but I don't think it will help you much. The RegenThread is what can be suspended/resumed.
    I didn't had a close look to your code, no. But how do you want to archive your goal that the thread runs even if the server is stopped? Server stopped = Java stopped = Your code stopped.
     
  13. Offline

    IDragonfire

    Thats true ...
    Only possible is to fire the event at startup (or after all plugins loaded and maybe a delay) and let the plugin decides what happen ...
     
Thread Status:
Not open for further replies.

Share This Page