Solved AsyncRepeatingTask Not Working Properly, Replacement Needed.

Discussion in 'Plugin Development' started by Build_and_Break, May 31, 2014.

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

    Build_and_Break

    Hello,

    in my onEnable() section, I have a timer system set up that automatically logs each online player's location every configured amount of seconds. It does this in an AsyncRepeatingTask. Code:

    Code:java
    1. this.getServer().getScheduler()
    2. .scheduleAsyncRepeatingTask(this, new Runnable() {
    3. public void run() {
    4. int number = getConfig().getInt("interval", 15);
    5. if (number != 0) {
    6. number--;
    7. getLogger().info("1 was subtracted from number.");
    8. } else {
    9. // -----> Main Logger <-----\\
    10. try {
    11. getLogger().info("2nd try started.");
    12. log = MySQL
    13. .openConnection()
    14. .prepareStatement(
    15. "INSERT INTO LW (`ign`, `w`, `x`, `y`, `z`) VALUES (?, ?, ?, ?, ?,);");
    16. getLogger().info("2nd try finished.");
    17.  
    18. for (Player p : Bukkit.getOnlinePlayers()) {
    19. Location loc = p.getLocation();
    20. log.setString(1, p.getName());
    21. log.setString(2, loc.getWorld().getName());
    22. log.setNString(3,
    23. String.valueOf(loc.getX()));
    24. log.setNString(4,
    25. String.valueOf(loc.getY()));
    26. log.setNString(5,
    27. String.valueOf(loc.getZ()));
    28. log.execute();
    29. getLogger().info("Data logged for " + p.getName());
    30. }
    31.  
    32. } catch (SQLException e) {
    33. e.printStackTrace();
    34. }
    35.  
    36. number = getConfig().getInt("interval");
    37. }
    38. }
    39. }, 0L, 20L);


    As you can see, I have some loggers in place because I've been working on debugging this. I realize the whole thing is deprecated, and that's why I'm here. Even if multiple players are online, the only message that is returned to the console is this:

    Code:java
    1. getLogger().info("1 was subtracted from number.");


    Every 15 seconds, as planned, it does not echo that as the number is equal to zero, but none of the other messages are returned and nothing is really logged.

    Since it's deprecated, I'm not all that surprised, and I won't be if the AsyncRepeatingTask is just not a valid method of doing this. If anyone can spot any other errors I may have, please let me know. If you know of another working way to do this and can confirm that the ART I'm using will never work, please let me know below. I'm kinda new to this stuff.

    Full Code: https://github.com/TacticalCactupi/LW

    Thanks,
    larsima/TacticalCactupi/Build_/Chris
     
  2. Offline

    teej107

    Every time your task executes, this code
    Code:java
    1. int number = getConfig().getInt("interval", 15);
    will always set number back to what it was.
    Either have the task change the number in your config or declare the int in the class rather than the runnable.
     
  3. Offline

    xTrollxDudex

    Build_and_Break
    Most of the methods you are using are not thread safe. You may want to wrap with immutable before accessing in async.
     
  4. Offline

    Build_and_Break

    Okay, I think I get what you're saying. Wouldn't declaring it outside of the ART work just as well so it wouldn't just keep flipping between 14 and 15?

    I've scrapped the old AsyncRepeatingTask and wrapped the old contents in this:

    Code:java
    1. BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
    2. scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
    3. @Override
    4. public void run() {
    5. // Do something
    6. }
    7. }, 0L, 20L);


    However, It appears the number doesn't reset, it just keeps running the stuff in lines 13, 14, 15, and 16. How would I reset the number to whatever is defined in the config? I guess declaring it like this doesn't work:

    Code:java
    1. number = getConfig().getInt("interval", 15);


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 1, 2016
  5. Offline

    teej107

    Build_and_Break
    Code:java
    1. number = getConfig().getInt("interval", 15);
    Will always be to whatever the config says. After doing number-- or other things with the int, you can always set it back by using the above code again or by just assinging it a different number.
     
  6. Offline

    Build_and_Break

    I am doing that on line 39 but it doesn't set it back...

    Code:java
    1. BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
    2. scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
    3. int number = getConfig().getInt("interval", 15);
    4. @Override
    5. public void run() {
    6. if (number != 0) {
    7. number--;
    8. getLogger().info("1 was subtracted from number.");
    9. } else {
    10. // -----> Main Logger <-----\\
    11. try {
    12. getLogger().info("2nd try started.");
    13. log = MySQL
    14. .openConnection()
    15. .prepareStatement(
    16. "INSERT INTO LW (`ign`, `w`, `x`, `y`, `z`) VALUES (?, ?, ?, ?, ?,);");
    17. getLogger().info("2nd try finished.");
    18.  
    19. for (Player p : Bukkit.getOnlinePlayers()) {
    20. Location loc = p.getLocation();
    21. log.setString(1, p.getName());
    22. log.setString(2, loc.getWorld().getName());
    23. log.setNString(3,
    24. String.valueOf(loc.getX()));
    25. log.setNString(4,
    26. String.valueOf(loc.getY()));
    27. log.setNString(5,
    28. String.valueOf(loc.getZ()));
    29. getLogger().info("Beginning log for" + p.getName());
    30. log.execute();
    31. getLogger().info("Data logged for " + p.getName());
    32. }
    33.  
    34. } catch (SQLException e) {
    35. e.printStackTrace();
    36. }
    37.  
    38. number = getConfig().getInt("interval", 15);
    39. }
    40. }
    41. }, 0L, 20L);


    teej107 ^
     
  7. Offline

    Relicum

    Save of the messing about and change to this

    Code:java
    1. BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
    2. scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
    3.  
    4. @Override
    5. public void run() {
    6. if(Bukkit.getOnlinePlayers().length != 0) {
    7.  
    8. getLogger().info("There are players online lets start logging");
    9.  
    10. // -----> Main Logger <-----\\
    11. try {
    12.  
    13. log = MySQL
    14. .openConnection()
    15. .prepareStatement(
    16. "INSERT INTO LW (`ign`, `w`, `x`, `y`, `z`) VALUES (?, ?, ?, ?, ?,);");
    17. getLogger().info("Start looping online players");
    18.  
    19. for (Player p : Bukkit.getOnlinePlayers()) {
    20. Location loc = p.getLocation();
    21. log.setString(1, p.getName());
    22. log.setString(2, loc.getWorld().getName());
    23. log.setNString(3,
    24. String.valueOf(loc.getX()));
    25. log.setNString(4,
    26. String.valueOf(loc.getY()));
    27. log.setNString(5,
    28. String.valueOf(loc.getZ()));
    29. getLogger().info("Beginning log for" + p.getName());
    30. log.execute();
    31. getLogger().info("Data logged for " + p.getName());
    32. }
    33. getLogger().info("Finished looping online players");
    34.  
    35. } catch (SQLException e) {
    36. e.printStackTrace();
    37. }
    38.  
    39.  
    40. }
    41. getLogger().info("Tasks ended should restart in 15 seconds");
    42. }
    43. }, 100L, 20L * getConfig().getLong("interval",15L));


    Basically the task will run if there are players online, if not will wait another 15 seconds. I have also set a 5 second delay for the first task to allow the server to get fully loaded before running the first time. You also need to store the interval as a long to. Not tested it but should work for you.
     
  8. Offline

    Garris0n

    If you never modify the number, what exactly did you expect?

    Declare it inside the anonymous class instead of the method.
     
  9. Offline

    Build_and_Break

    Relicum Okay, thanks. Wasn't sure if that'd work, I'll test that when I get home. Thanks!

    Garris0n Look again.
    Code:java
    1. if (number != 0) {
    2. number--;
    3. getLogger().info("1 was subtracted from number.");
    4. } else {


    And declaring it in the anonymous class wouldn't work. The Async I was originally using wouldn't take variables not define inside it unless the variable was something like getConfig.
     
  10. Offline

    Garris0n

    So it is not working after you did that?
     
  11. Offline

    mythbusterma

    Don't run SQL queries in the main thread (I.e. using a sync task), if the database is remote this could cause an arbitrarily long delay due to connection issues, plus a large database could take a long time to query. That being said, using the Bukkit API from a worker thread is certianly not the best route to go either, you're going to need two threads.
     
  12. Offline

    Build_and_Break

    Garris0n It didn't go back to subtracting the number after running through the 15th time. I'm using Relicum's strategy now.

    SOLVED : Confirmed that @Relicum's method works. I've got a few more errors to work out before this plugin releases. Thanks guys!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 1, 2016
Thread Status:
Not open for further replies.

Share This Page