#[Code-Improvement] Discord Java Webhook cause performance issue on (minecraft -> Java8) server.

37 messages Β· Page 1 of 1 (latest)

midnight kettle
#

Basically i created this code, which i run every 6 seconds, if the Queue Data is not empty.
base on some performance measuring the getResponceCode causing lag. Not sure why 😦

any idea how to improve this code for Java 8

    public static void SEND(String webhookurl,String data) {
        if (webhookurl != null) {
            if (webhookurl.contains("EXAMPLE")) {return;}
            if (!webhookurl.startsWith("https://discord.com/api/webhooks")) {return;}
            JsonObject json = new JsonObject();
            json.addProperty("content",data);
            json.addProperty("username","Janna-Log");
            try {
                URL url = new URL(webhookurl);
                HttpsURLConnection web = (HttpsURLConnection) url.openConnection();
                web.setRequestProperty("Content-Type", "application/json");
                web.setRequestMethod("POST");
                web.setDoOutput(true);
                OutputStream stream = web.getOutputStream();
                stream.write(json.toString().getBytes(StandardCharsets.UTF_8));
                stream.flush();
                stream.close();
                int wcode = web.getResponseCode();
                int rlr = web.getHeaderFieldInt("X-RateLimit-Remaining",-1);
                int rls = web.getHeaderFieldInt("X-RateLimit-Reset-After",-1);
                if (wcode>204 || wcode<200) {
                    ModFile.LOGGER.error("Error: Discord Webhook HTTP CODE: "+wcode);
                    ModFile.LOGGER.warn("Remaining Requests:"+rlr+" (Reset in: "+rls+"s)");
                }
                web.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
analog mistBOT
#

βŒ› This post has been reserved for your question.

Hey @midnight kettle! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

lavish timber
#

If you are working on a Minecraft plugin you should execute network requests asynchronously if possible

midnight kettle
#

asynchronously in terms of not having a fixed schedule (like every 6 second), or in terms of CPU Core distribution?

lavish timber
#

You can just use BukkitRunnable for this task

#
new BukkitRunnable() {
  public void run() {
    SEND(webhookurl, data);
  }
}.runTaskAsynchronously(plugin);
midnight kettle
#

i find it weird that the InputStream causing the lag. not the outputstream, the Data i send to discord, looks be smooth

lavish timber
midnight kettle
#

Its Forge Mod ^^ i need to see how asynchronous works there

lavish timber
#

Oh

#

I see

#

I don't know if Forge has a dedicated method of doing this, but you can always resort to using an ExecutorService

midnight kettle
#

and i am not sure if its better to keep the connection open, and just write stuff, or just reopen it for error prevention

lavish timber
#

You should create a new http connection every time you want to send a new message to a webhook

midnight kettle
#

so the way i made it right now then πŸ˜„

lavish timber
#

There is no reason to keep it open and I don't think you can even do that

#

Yeah

#

So one way is to use the "Java" method - create an ExecutorService instance with ExecutorService service = Executors.newCachedThreadPool(); and submit your task with its submit(Runnable) method

#

So you can do something like service.submit(() -> SEND(webhook, data));

#

That should work but you should remember not to use any Forge api from inside of the submitted runnable

midnight kettle
#

i found this in forge πŸ˜„
ServerLifecycleHooks.getCurrentServer().submitAsync(Runnable)
that shoudl be equivalent?

lavish timber
#

Yeah I was about to mention this

#

And it's preferred to use forge specific api over the former method

midnight kettle
#

thx, ima stress test that with 1 sec delay

#

thing is, whats the Downsite of the async ?

#

compare to the normal way

#

everything needs to have a downsite ^^

lavish timber
#

Yep, there is a big downside: you have to worry about thread safety which is a completely separate topic

#

I suggest reading up on the subject. You don't have to worry about it when using async tasks to submit a http request, write something to a file, etc.

#

But if you want to modify a variable, call another method from your code, call Forge's API, etc, you have to take that into account

midnight kettle
#

does polling a queue count as modifying a variable πŸ€”

lavish timber
#

polling should be safe, popping on the other hand is not safe and should be done in a synchronized block/method

midnight kettle
#

Basically my events. put the Stuff in a Queue<List> . my Timer, pools 9 elements from that Queue and put them in a Stringbuilder. and send that to HTTP. (to prevent Discord Json Char limit of 2000).

lavish timber
#

To be safe you can do everything synchronously and only make the http request asynchronously

midnight kettle
#

yeah sure

lavish timber
#

Good luck