How to return the string.

Discussion in 'Spigot Plugin Development' started by Jonnyo101, Jun 2, 2017.

  1. Hello. How would i return the string from this method.

    Code (Text):
        public String Fetch(String TableName, String KeyId, String ColumnName, Callback<String> value) {

           
            FetchEntry(TableName, KeyId, ColumnName, new Callback<ResultSet>() {
       
                @Override
                public void execute(ResultSet value) {
                    try {
                        value.first();
                        String returnvalue = value.getString(1);
                        // ^^ I want to return this value.
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
           
                }

            });

            return "";

        }
     
  2. Mas

    Mas

    • Agree Agree x 1
  3. I know how to you a "Callback" is there no way to make the method call return the value ?
     
  4. I don't think you do. This is a promise that the data will be gained back at some point, perhaps not immediately after. Use the callback to do something with that value after it is obtained. Read the doc you were linked to.
     
  5. Mas

    Mas

    Not if you want to execute the task/query in an async thread. It's also worth mentioning you should switch back to the main thread before calling the callback/consumer.
     
  6. You could just predefine the variable or call return inside the try { block }.

    Code (Text):
    // pre defining
    String s = "";
    try {
      s = "New value";
    }

    return s;
    // or

    Code (Text):
    try {
      return "New value";
    }

    return "";
    EDIT: oops, async
     
    #6 ExpDev, Jun 2, 2017
    Last edited: Jun 2, 2017
  7. Hi i tried that but it did not work. I think its because FetchEntry is called on another thread.

    I now have this code. That is returning the value from the SQLDataBase. Is there anything wrong in doing it like this ?

    Code (Text):
    private String FetchEntry(String TableName, String KeyID, String ColumnName) {
       
            final CountDownLatch latch = new CountDownLatch(1);
            final String[] result = new String[1];

            Thread serverThread = new Thread(() -> {
           
                    try {  
                   
                        ResultSet resultSet = GetConnection().createStatement().executeQuery("SELECT " + ColumnName + " FROM " + TableName + " WHERE IdKey='" + KeyID + "';");
                        latch.countDown();
                        resultSet.first();
                        String returnvalue = resultSet.getString(1);
                        result[0] = returnvalue;

                    } catch (SQLException e) {
                        e.printStackTrace();
                    }  
            });
               
            serverThread.start();
           
            try {
                latch.await();  
                return result[0];
            } catch (InterruptedException e    ) {
                e.printStackTrace();
            }
       
            return "NULL";

        }
     
  8. Mas

    Mas

    That won't work. The JRE won't wait for the async task to complete before returning the String, so you're just going to get an empty string each time.

    That will block the main thread until the result is found. Just use a Callback :p
     
    #8 Mas, Jun 2, 2017
    Last edited: Jun 2, 2017
  9. Why do you have two callbacks?
     
  10. Hello i have tested it and it does not return a empty string and it does not block the main thread.
     
  11. electronicboy

    IRC Staff

    You are blatantly blocking the main thread with a latch. your sql query may be on another thread (Which, is somewhat stupid to allocate a new thread when there is a thread pool already exposed by bukkit and the scheduler, or creating your own thread pool if you *really* don't wanna be limited to the tick cycle of the server, so that you're not creating new threads to run a trivial query on), but you're blocking the main thread with the latch, albeit, you've not even programmed your latch properly, so should processing the results take longer than planned after the execution of the query, you're going to break stuff.
     
  12. Didn't realize it was a sync... oops.
     
  13. Really. If i do the sql call on the main thread i see a noticeable lag spike in mobs moving when pulling data.
    With that above method i can run it 10 times a second and i do not see a lag spike.
     
  14. electronicboy

    IRC Staff

    Please tell me how in any shape or form, without the blocking of the latch that you added that *will* block the main thread, will even be able to guarantee that the result from the database it returned?
    You need to understand the concept of threading and concurrency because that code clearly shows that you don't understand the concept of threading.

    if you create a latch and then spawn a new thread which manipulates that latch after a while, and await on the latch, you're stuck waiting until the latch is told to no longer be blocking, which is what a latch is and does. 10 times a second on a trivial query on what is likely a fresh database will hardly incur much time, it will show up nicely in timings, but on its own, won't really be a massive performance crunch until you have stuff going on on the server, or the size of the table increases to the point where queries actually can take time.
     
  15. Okay i will just use a callable. I wanted a way that is more pleasing the eye when doing sql calls.
    But i am guessing you can not just make the method return the value directly.

    And no i never learnt threading it was just a wild stab in the dark.
    And the database has 20,000+ entry's and i tested on one of my server that have 100+ players on and it was not lagging to a presumed it was okay.

    Thanks for the criticism

    If it can be done can you point me in the right direction to have a async sql call that returns the value directly from the method.
     
  16. Mas

    Mas

    It can't be done, that's what we've been telling you this whole thread :p If you took some time to learn about threading you would realise it too.
    I'm not sure why you're so desperate to be able to return directly from the method. There really isn't much of an advantage?
     
  17. I am writing this as a core for the network for other plugins to use.
    and it would keep the code size down in the game plugins and the readability up. !

    But i will take your advice and read up on threading.