What's the best way to repeat tasks at set intervals?

Discussion in 'Plugin Development' started by fullwall, Jan 26, 2011.

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

    fullwall

    I am in the midst of writing a plugin that has a counter value and a threshold. I need to increment the value every x seconds or ticks until it reaches that threshold. I was wondering what the best way to implement this repeat increment would be? I was going to go with a Timer Task schedule, but I'm not sure if that runs on its own thread continually and it depends on the user time, so could get inaccurate.

    I have heard about org.bukkit.Server.getTime(), but how do I repeatedly check that value after the interval? Obviously I don't want while loops etc. because that would bottleneck the server...

    Also, my plugin requires storing a value per-player every time this task is called. I'm not sure of the best way to handle that. I could write the values to a file every time but that would also result in slowdowns due to file read speeds. What is the best way to do this?

    Thanks in advance.
     
  2. Offline

    eisental

    Funny that these are exactly the same problems i'm facing with my plugin.

    It's currently impossible to sync with the game time. So, if I'm not mistaken there's no safe way to run tasks at set intervals. You can use a timer and check the server time at some regular interval but calling bukkit methods from the timer task would probably lead to weird server crashes.

    About the second question, I guess the normal way to do it would be to keep the per-player values in a Map in memory and only save it to file once the server shuts-down. Since there's still no way to know when the server shuts-down the only option is to save it to file every time you make a change (that's what I do). It shouldn't take so much time unless you're changing values very quickly. In that case I think its safe to create a timer task for saving the current state of your Map object every few minutes or so. But you still risk losing some data.
     
  3. Offline

    fullwall

    Oh really. No proper way to run it regularly? :(

    The time that the values change is user-configurable, so it could become an issue. I could save it in onDisable()? I guess saving to file regularly is just a last resort for me, as its per-user and could potentially become large if a lot of different people are joining the server.
     
  4. Offline

    Raphfrk

    I made a suggestion and submitted a pull request to allow events to be sent from other threads to the main thread. This would allow thread syncing.

    However, in the conversation with the dev responsible, it looks like we are talking past each other.

    Given the amount of talk that the feature isn't needed, I think it would be easier to just include it :).
     
  5. Offline

    eisental

    It won't help you to save it in onDisable(), it's never called (at least not when you shutdown the server).

    @Raphfrk I'm watching the issue on redmine and would've commented if I knew anything about the minecraft server. In any case this is obviously one of the most important missing features. I was going to ask some questions about it, but maybe I should look at your commit code before making myself look stupid :)
     
  6. Offline

    Raphfrk

    The code isn't really that complex. The only question is how to trigger the poll function from the main thread.

    Basically, I have updated the server so that once per clock tick it calls dispatchPendingAsyncEvents(). However, I may have placed the poll call in a dangerous place.

    This function checks if there are any events in the event queue and executes them one at a time. This means that these events get executed by the main queue.

    There are also 2 methods for plugins to add events to the async queue.
     
  7. Offline

    fullwall

    Well, my ScheduledExecutorService seems to work OK for the time being...
     
  8. Offline

    Raphfrk

    Actually, if you are just writing info to a file every N seconds, then there is no problem. It is just it you want to do something with the API from another thread.

    Ofc, make sure you use the synchronized system to make sure it is thread safe.
     
  9. Offline

    Cmars

    timer.schedule can be pretty nice.
     
  10. Offline

    eisental

    Any news about this? I would love to test your dispatcher, but I couldn't manage to compile your craftbukkit fork. It also has to be merged with the latest bukkit/craftbukkit for it to work with my plugin. If you can post jars somewhere it would be very helpful.
     
  11. Offline

    The_Guest

    Yea, right up to the point where it crashed the server. [​IMG]
     
  12. Offline

    TheBeefiest

    If the timing itself isn't imperative: You can increment a counter onPlayerMove , and only do your updating every playercount x 6 or so. That way you have easy periodic processing without slowing anything down.
     
  13. Offline

    eisental

    unless nobody moves
     
  14. Offline

    TheBeefiest

    which is almost impossible with tons of people online
     
  15. Offline

    Afforess

    Assumptions are always a bad idea.

    Anyway, what if something still needs to work without a player moving? (Pretty sure player move isn't called in a boat or minecart.)
     
  16. Offline

    The_Guest

    It could be solved by doing an if statement questioning the amount of players online. Also isn't there an OnEntityMove? Those damn animals are always moving around.
     
  17. Offline

    void420

    Having all multi-threaded plugins doing their own polling every time something moves is not very good. We really just need a thread safe way to call a custom event or callback on the main thread to do this kind of stuff efficiently.
     
  18. Offline

    Afforess

    Still a terrible, terrible way to do it. Hmod had a great feature to create an event that runs in x ms. Why can't bukkit?
     
  19. Offline

    darknesschaos

  20. Offline

    The_Guest

    Well yea, its awful regardless. I will also be happy when/if we get an event like that.
     
  21. Offline

    NathanWolf

    I would also love that. I use player move events calling a scheduler now to simulate this- but of course it only works if someone is moving around.
     
Thread Status:
Not open for further replies.

Share This Page