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

Some improvements to ThreadDispatcher API #2014

Open
Steanky opened this issue Mar 2, 2024 · 2 comments
Open

Some improvements to ThreadDispatcher API #2014

Steanky opened this issue Mar 2, 2024 · 2 comments

Comments

@Steanky
Copy link
Contributor

Steanky commented Mar 2, 2024

The ThreadDispatcher class is a non-internal and potentially useful part of the API. It would allow users to implement their own systems that emulate Minestom's parallel entity ticking, and leverage Acquirable on their own objects to guarantee thread-safety. However, there are problems with how it is currently implemented:

  • The class is hardcoded to only work with Entity (and subclasses).
  • Users cannot control the names of the threads. They will always look like "Ms-tick-n", which could cause potential confusion if they are used in other contexts.

To address these concerns, I've committed some improvements to this branch on my fork, which are summarized below. They are designed to be drop-in and should not break existing code.

  • Instead of hardcoding Entity, ThreadDispatcher supports any implementation of the new functional interface AcquirableSource<T>, which specifies Acquirable<? extends T> getAcquirable
  • Entity now implements AcquirableSource<Entity>
  • TickThread has a new constructor which accepts a string for its name, rather than generating a hardcoded one from its integer ID
  • A new static constructor method has been added to ThreadDispatcher that accepts an IntFunction<String> to generate unique names for each tick thread
  • ThreadDispatcher has additional/clarified documentation in some places
  • All non-demo subclasses of Entity override getAcquirable to return their own, more specific, type. This makes working with the acquirable API a bit easier, as users will not have to cast to more specific Entity subclasses when calling methods like Acquirable#sync

If these changes are desirable, I will make a pull request. Feedback is appreciated and I would be happy to make further modifications if necessary!

Additional note: on my branch, I opted to make the new ThreadDispatcher constructor accept an IntFunction<String> rather than IntFunction<TickThread>. Although the latter is strictly more flexible, I opted with the former to avoid exposing a class marked as @ApiStatus.Internal. However, I would argue that TickThread should be made part of the public API, considering that ThreadDispatcher is, and it would allow for more fine-grained control in combination with the ThreadDispatcher enhancements.

@mworzala
Copy link
Member

mworzala commented Mar 5, 2024

I think the changes seem pretty reasonable, although I would prefer not to expose the api unless there is a good reason. Do you have a use case?

@Steanky
Copy link
Contributor Author

Steanky commented Mar 6, 2024

Assuming you're referring to exposing TickThread: users may benefit from changing thread priority, or making the tick threads daemons. A tick-based scheduler implementation might want to use this. Without daemon threads, such a scheduler would need to explicitly invoke ThreadDispatcher#shutdown.

Additionally, users might want to implement an equivalent of Acquirable#currentEntities for their own Acquirable objects. I don't see a way of doing this without reading the entries list from the tick thread.

It would also allow for a slightly nicer way of making new ThreadDispatchers (IntFunction<TickThread> instead of IntFunction<String>)

If it's going to be made non-internal, I suggest a few additional changes:

  • TickThread#entries() should return an immutable view of the internal list
  • ThreadDispatcher can access the mutable internal list directly through a package-private method

The point being, it's probably an error if the user modifies the partition list directly (should be done through ThreadDispatcher methods)

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

No branches or pull requests

2 participants