Will this cause me any problems?

Discussion in 'Plugin Development' started by amitlin14, Jun 21, 2013.

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

    amitlin14

    Currently im running a repeating Sync task every 60 minutes, inside the sync task i update the players info in each of their respective profiles, and then i run an async task which saves the updates all of the profiles into a MySQL database, then the algorithm goes through the profiles again, flushing all of the cached offline players.

    this is the save algorithm:

    Code:java
    1. public class SaveTask implements Runnable {
    2.  
    3. private PTP ptp;
    4. private PlayerSave task;
    5.  
    6. public SaveTask(PTP ptp) {
    7. this.ptp = ptp;
    8. task = new PlayerSave(ptp);
    9.  
    10. }
    11.  
    12. @SuppressWarnings("static-access")
    13. @Override
    14. public void run() {
    15. for (PlayerProfile d : ptp.pinfo)
    16. {
    17. Bukkit.broadcastMessage("Updating Profiles, expect slight lag.");
    18.  
    19. OfflinePlayer player = Bukkit.getPlayer(d.owner);
    20. d.playtime = player.getLastPlayed() - player.getFirstPlayed();
    21. d.money = ptp.economy.getBalance(d.owner);
    22.  
    23. if (player.isOnline())
    24. {
    25. Player oplayer = Bukkit.getPlayer(d.owner);
    26. d.hometown = oplayer.getMetadata("town.name").get(0).asString();
    27. d.kills = oplayer.getMetadata("kills").get(0).asInt();
    28. d.ckills = oplayer.getMetadata("cKills").get(0).asInt();
    29. d.playtime = System.currentTimeMillis() - player.getFirstPlayed();
    30. }
    31. }
    32.  
    33. Bukkit.getScheduler().runTaskAsynchronously(ptp, task);
    34.  
    35. for (PlayerProfile d : ptp.pinfo)
    36. {
    37. OfflinePlayer player = Bukkit.getPlayer(d.owner);
    38. if (!player.isOnline())
    39. ptp.pinfo.remove(d);
    40. }
    41. }
    42. }
    43.  
    44. class PlayerSave implements Runnable {
    45. PTP ptp;
    46.  
    47. public PlayerSave(PTP ptp) {
    48. this.ptp = ptp;
    49. }
    50.  
    51. @Override
    52. public void run() {
    53. for (PlayerProfile pp : ptp.pinfo)
    54. {
    55. ptp.mysql.INSERT(pp.owner, pp.playtime, pp.hometown, pp.kills, pp.ckills, pp.money);
    56. }
    57. }
    58. }


    saveTask is run every 60 minutes, like this:

    Code:java
    1. task = new SaveTask(this);
    2. save = Bukkit.getScheduler().runTaskTimer(this, task, 20 * 60 * 60, 20 * 60 * 60);
    3.  


    and when the server shuts down, like this:

    Code:java
    1. Bukkit.getScheduler().cancelTask(save.getTaskId());
    2. task.run();


    I have very minimal knowledge in threads and tasks and stuff of that sort, so im hoping that people that are a bit more experienced in this field than me could answer me a very simple question:

    Will this way of doing things cause any problems? currently i have no way of testing it, since im making this for a server, which gets the info using metadata from other plugins.

    im not certain this use of tasks is ok, is it fine to run a sync task, and create an async task from it? are there any better ways of doing this? will this cause lag?

    Im hoping you can answer these questions for me, thanks :)
     
  2. Offline

    Nitnelave

    The issue with multithreading is when two threads write the same data at the same time (or one writes, and one reads), as this can cause some issues. For example, if you have a global variable counter (let's say for now it is 1), and two threads do counter++ at the same time, you could have both threads read the current value of counter (1) and then both write counter = 2, so after two counter++, you get counter == 2, which is wrong.

    But in your case, it's quite simple (though your approach is wrong). If you keep the way you have it, you have to pray that it writes to the database faster than the cleanup task, because that's going to be a race! You don't want that. You should construct a copy of the playerinfo that you will pass to the saving task, so it has its own data that it can read at its own pace, while the main thread cleans up the main player info.
     
Thread Status:
Not open for further replies.

Share This Page