Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-437 Improve schedulers #486

Merged
merged 32 commits into from
Nov 22, 2024
Merged

Conversation

BlackBaroness
Copy link
Contributor

@BlackBaroness BlackBaroness commented Nov 12, 2024

Sorry for being late! Will finish soon! Closes #437.

I am currently reviewing and improving schedulers for all platforms:

  • Core
  • Bukkit
  • BungeeCord
  • Sponge
  • Velocity
  • Fabric
  • Jda
  • Minestom

About BungeeCord

BungeeCord's own scheduler is not efficient because it creates an unlimited cached thread pool for
each plugin and just uses it:
https://github.com/SpigotMC/BungeeCord/blob/master/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java
https://github.com/SpigotMC/BungeeCord/blob/master/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java

It also just blocks the threads if a task with a delay is received (by using Thread.sleep),
so the thread won't be doing anything useful even if there is more tasks available

I decided to use the Core scheduler instead, since it's more efficient by at least providing a max cap

About Velocity

Velocity's own scheduler is very similar to BungeeCord's one
Each plugin has it's own uncapped cached thread pool
That doesn't look good
https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/plugin/loader/VelocityPluginContainer.java
https://github.com/PaperMC/Velocity/blob/dev/3.0.0/api/src/main/java/com/velocitypowered/api/plugin/PluginContainer.java

I decided to use the Core scheduler instead, since it's more efficient by at least providing a max cap

About Bukkit

Looks good, only small improvements were made

About Minestom

Don't see anything to improve, it's fine. Also the Minestom's own scheduler is good, so no need to use our own

About Sponge

Sponge provides a scheduler similar to Bukkit, so I implemented a wrapper for one

About JDA

I don't think there is a specific implementation for JDA, so we should just use the one from Core

About Fabric

Was implemented by @huanmeng-qwq

@BlackBaroness BlackBaroness marked this pull request as draft November 12, 2024 10:51
@BlackBaroness BlackBaroness changed the title [WIP] Improve schedulers Improve schedulers Nov 12, 2024
@BlackBaroness
Copy link
Contributor Author

@Rollczi hey, looks like I finished for now, can you help me with Fabric and review the code?

@huanmeng-qwq
Copy link
Contributor

huanmeng-qwq commented Nov 13, 2024

@BlackBaroness Hi, I noticed that you can't solve the fabric platform. Since I don't have permission to submit changes directly to the pr, I will create a new PR and submit it to your fork repository.

* add fabric server scheduler

* fix server, update ExampleCommand

* del mixin

* add FabricClientScheduler

* fix later

* fix later, update ClientCommands
@BlackBaroness
Copy link
Contributor Author

@BlackBaroness Hi, I noticed that you can't solve the fabric platform. Since I don't have permission to submit changes directly to the pr, I will create a new PR and submit it to your fork repository.

Thanks, I merged it

@BlackBaroness BlackBaroness marked this pull request as ready for review November 13, 2024 14:57
@Rollczi
Copy link
Owner

Rollczi commented Nov 14, 2024

Using platform schedulers (BungeeCord, Velocity) can improve performance by sharing unused threads in the cached pools

@BlackBaroness
Copy link
Contributor Author

BlackBaroness commented Nov 15, 2024

Using platform schedulers (BungeeCord, Velocity) can improve performance by sharing unused threads in the cached pools

I believe an uncapped cached pools dedicated to a single plugin only is a bad idea. Especially if you look on how delayed tasks were implemented - they create a thread and then call Thread.sleep inside it, so the pool can grow so much without even doing anything. If this pool was used by the entire proxy, of course it would be nice (like craftbukkit does), but in this case... I feel like the BungeeCord Scheduler is a mistake by design

Velocity is slightly better, but still has an uncapped pool. What if several players will spam async commands?

Proxies are designed to handle thousands of players online concurrently, an uncapped pool can become a disaster when commands are expensive enough to make threads busy

Or, for BungeeCord... Delayed tasks are usually used by cooldown system. What if we have a /login command (what is something all players use at least once) with 2s cooldown? If 200-300 players joined after restart, everyone executed /login (what is async itself) - 200-300 threads were created and then 200-300 threads more created to make delayed tasks (as BungeeCord doesn't use scheduled pools). That's insane

* add fabric server scheduler

* fix server, update ExampleCommand

* del mixin

* add FabricClientScheduler

* fix later

* fix later, update ClientCommands

* extend SchedulerExecutorPoolImpl
@Rollczi
Copy link
Owner

Rollczi commented Nov 15, 2024

Using platform schedulers (BungeeCord, Velocity) can improve performance by sharing unused threads in the cached pools

I believe an uncapped cached pools dedicated to a single plugin only is a bad idea. Especially if you look on how delayed tasks were implemented - they create a thread and then call Thread.sleep inside it, so the pool can grow so much without even doing anything. If this pool was used by the entire proxy, of course it would be nice (like craftbukkit does), but in this case... I feel like the BungeeCord Scheduler is a mistake by design

Velocity is slightly better, but still has an uncapped pool. What if several players will spam async commands?

Proxies are designed to handle thousands of players online concurrently, an uncapped pool can become a disaster when commands are expensive enough to make threads busy

Or, for BungeeCord... Delayed tasks are usually used by cooldown system. What if we have a /login command (what is something all players use at least once) with 2s cooldown? If 200-300 players joined after restart, everyone executed /login (what is async itself) - 200-300 threads were created and then 200-300 threads more created to make delayed tasks (as BungeeCord doesn't use scheduled pools). That's insane

Okay, this is actually true, let's use pool with limited threads.

@Rollczi
Copy link
Owner

Rollczi commented Nov 15, 2024

I will try fix some issues

@Rollczi
Copy link
Owner

Rollczi commented Nov 15, 2024

@BlackBaroness Thank you for your substantive comments, I implemented them into the old scheduler implementation. I also simplified the code for Farbric scheduler, what do you think, that should work? @huanmeng-qwq

@BlackBaroness
Copy link
Contributor Author

BlackBaroness commented Nov 16, 2024

@Rollczi, looks nice! (not about Fabric)

I noticed you created the SchedulerMainThreadBased class and I believe its naming is pretty strange, how about the MainThreadBasedScheduler?

Also, this new abstraction could be used for Sponge scheduler, I think.

@BlackBaroness
Copy link
Contributor Author

Also, on Sponge we have both client.scheduler and server.scheduler. I am not sure which one to use, so used the server one. LiteCommands can be installed on clients without a server I guess, it doesn't really depend on server. But how do we specify which scheduler should we use?

We could make it like if (server.available) server else client on platform init, but what if both server and client are available? I am not sure if it's possible, maybe on singleplayer the server runs in completely different process

@Rollczi
Copy link
Owner

Rollczi commented Nov 16, 2024

I noticed you created the SchedulerMainThreadBased class and I believe its naming is pretty strange, how about the MainThreadBasedScheduler?

okay, I will rename it

Also, this new abstraction could be used for Sponge scheduler, I think.

I don't think so, this will more complicated... let's follow the principe KISS (Keep it simple stupid)

@Rollczi
Copy link
Owner

Rollczi commented Nov 16, 2024

Also, on Sponge we have both client.scheduler and server.scheduler. I am not sure which one to use, so used the server one. LiteCommands can be installed on clients without a server I guess, it doesn't really depend on server. But how do we specify which scheduler should we use?

We could make it like if (server.available) server else client on platform init, but what if both server and client are available? I am not sure if it's possible, maybe on singleplayer the server runs in completely different process

user should use LiteFabricFactory.server() or LiteFabricFactory.client() depends on his implementation

@Rollczi Rollczi changed the title Improve schedulers GH-437 Improve schedulers Nov 16, 2024
@BlackBaroness
Copy link
Contributor Author

user should use LiteFabricFactory.server() or LiteFabricFactory.client() depends on his implementation

I talked about Sponge, not Fabric btw
We don't have an implementation-specific builder method there
Now I implemented a AbstractMainThreadBasedScheduler scheduler in Sponge + added an automatic server/client scheduler selection based on what is available. Looks much better now

I believe this PR is ready, if Fabric is ok

Copy link
Owner

@Rollczi Rollczi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for next improvements @BlackBaroness

…Scheduler.java

Co-authored-by: Norbert Dejlich <ndejlich5@gmail.com>
@Rollczi
Copy link
Owner

Rollczi commented Nov 22, 2024

Okay thanks @BlackBaroness and @huanmeng-qwq for your help! ❤️

@Rollczi Rollczi merged commit 4020847 into Rollczi:master Nov 22, 2024
7 checks passed
@BlackBaroness BlackBaroness deleted the improve-schedulers branch November 23, 2024 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clean up shchedulers
3 participants