Running MySQL Async

Discussion in 'Plugin Development' started by HeyAwesomePeople, Jun 9, 2014.

Thread Status:
Not open for further replies.
  1. Hello. Iv'e recently discovered why MySQL has to be used in an Async fashion, but fail to figure out how to do that. I have to call an MySQL method to retrieve the players credits from the database. Here is my code:

    PHP:
        public int getPlayerCredits(final UUID id) {
            final 
    int credits 0;
           
            
    Bukkit.getServer().getScheduler()
                    .
    runTaskAsynchronously(plugin, new Runnable() {
                        public 
    void run() {
                            
    Statement statement;
                            try {
                                
    statement plugin.mysql.openConnection().createStatement();
     
                                
    ResultSet res statement
                                        
    .executeQuery("SELECT * FROM players WHERE PlayerId = '"
                                                
    id "';");
                                
    res.next();
                                if (
    res.getString("Credits") != null) {
                                    
    credits Integer.parseInt(res.getString("Credits"));
                                }
                            } catch (
    SQLException sqlE) {
                                
    plugin.logToFile("There was an exception getting players credits!");
                                return;
                            }
                        }
                    });
            return 
    credits;
        }
    The only trouble I am having with is returning the actual credits amount.
    " credits = Integer.parseInt(res.getString("Credits"));" has an error on "credits" saying: "The final local variable credits cannot be assigned, since it is defined in an enclosing type". How do I fix this, or how do I make this code Async and still be able to return the credits?

    Thanks,
    HeyAwesomePeople
     
  2. Offline

    Azubuso

    HeyAwesomePeople A "final" modifier stops variables from being changed, in other words, what you're doing is the equivalent to making a constant in some other languages, making the statement "credits = Integer.parseInt(res.getString("Credits"));" throw an error as you're trying to modify it.

    TL;DR - Remove your final modifier.
     
  3. Azubuso "Cannot refer to a non-final variable credits inside an inner class defined in a different method". I must make it final for anything to work.
     
  4. Offline

    Azubuso

    HeyAwesomePeople Just do something like is;

    PHP:
    private int credits 0;
    public 
    int getCredits() {
        
    Bukkit.getScheduler().runTaskAsynchronously(plugin, new BukkitRunnable() {
            
    int fromDb 0;
            @
    Override
            
    public void run() {
                 
    fromDb // Your code
                 
    credits fromDatabase;
            }
        });
        return 
    this.credits;
    }
     
  5. Azubuso I'm using ASync for something else now, but this is still regarding the Async with MySQL.

    Here is my code:
    PHP:
        private BasicTeams team;
     
        public 
    BasicTeams getTeam(final Player p) {
            
    team null;
     
            
    Bukkit.getServer().getScheduler()
                    .
    runTaskAsynchronously(plugin, new Runnable() {
                        public 
    void run() {
                            
    long startTime System.nanoTime();
     
                            for (
    BasicTeams t plugin.teams) {
                                for (
    Player player t.getMembers()) {
                                    if (
    == player) {
                                        
    team t;
                                    }
                                }
                            }
     
                            
    long endTime System.nanoTime();
                            
    long duration endTime startTime;
                            
    Bukkit.broadcastMessage("Time taken to get team: "
                                    
    duration);
                        }
                    });
     
            return 
    this.team;
        }
    This code always returns null, no matter what. Meaning that when I do "team = t;" it's doing nothing. I have put debug messages in it and it does reach "team = t;". How do I fix this?

    NOTE: I know I am not supposed to use Bukkit methods in an Async'd method, but I'm just doing it for timing reasons.
     
  6. Offline

    xTrollxDudex

    HeyAwesomePeople
    Also note that your own implementation of mutable data must also be thread safe, your code is not thread safe from several points - bukkit API usage, collections, ect... However, I don't know if you are using a thread safe collection, so I may or may not be right about this statement, I will need more code to figure it out.
     
  7. xTrollxDudex Collections? I have never heard of that, and I don't know much, if at all about thread safety. This is my first time trying to do things Async'd. And I know Bukkit api shouldn't be used, and it's not, other than the timing the method.
     
  8. Offline

    xTrollxDudex

    HeyAwesomePeople
    No, not that. It's the list of teams and the teams members what I presume is non thread safe
     
  9. Offline

    JJkillzzz





    Hey, I need to talk to you. It's very important. Please message me on skype JJ.Violo. Please, I beg of you
     
  10. Offline

    Plo124

    HeyAwesomePeople
    1. A simple solution to this is to go to the next level up. Often this leads to an onCommand which does this. You can make your new task there and perform operations there. The downside is if everyone decides to get their balance at once thw JVM would have to make 20 new threads for 20 players which will take ages to complete. This us why running async tasks is better in a queuing system instead of globally.

    2. You could make a queuing system on 1 thread which every minute updates their global currency and store it locally too. This is reliable until you get server crashes.
     
    mazentheamazin likes this.
Thread Status:
Not open for further replies.

Share This Page