Skip to content
This repository was archived by the owner on Aug 28, 2021. It is now read-only.
This repository was archived by the owner on Aug 28, 2021. It is now read-only.

Develop new asyncio networking backend #26

@ntoskrnl4

Description

@ntoskrnl4

The current backend Quarry is good for quick and simple server implementations and handles nearly all of the networking for the server. However, I think we could benefit from developing our own networking backend, based off of asyncio.

AsyncIO in Python is significantly more performant in a single thread than a similarly written synchronous server implementation and can match the performance of a threaded server, all without the overhead of using separate threads (thread-safety, overhead, limited access to resources, etc). Other advantages of splitting from Quarry is that we are not bound to any of its constructs; for example its server classes, its API format, and its version support.

Per the starting discussion on Discord, here's my thoughts about how asyncio networking could be implemented:

The networking thread will consist of its own process (to avoid GIL bottleneck w/ main thread), and will run its own asyncio event loop to do networking. The networking thread will start the server, and create a networking queue for events. The networking queue will take in events that happen relating to players (eg. skeleton shot you, block was removed, etc). These will use internal event objects (probably dataclasses) and the networking thread will sort them out as needed and dispatch events to individual players' queues, at which point the event loop will pick up the events on each player and actually write the packet out to them and stuff.

Then, when a new player connects, the networking thread will manage the entire process of server list ping and login and such, until the player has mostly logged in. Then it will send an internal "player join" event back to the main server thread, and the server will give it the appropriate chunks to load.

Incoming data from the player relating to the main server thread (such as world movement or whatever) will be sent back to the main server with an event queue for the main server thread.

Things that don't involve the main server thread at all will never get passed to it; I can only think of this being chat and server commands, but perhaps PvP could be in this category as well.

That's my initial thought as to how async networking could be done. It passes a lot of the server functions into it but unless the server has 200 players on it I don't think it'd be too bad. Then again, we could also go with a simpler implementation where only incoming data events and outgoing data events are handled, and everything is done in the main server thread. This should also be something we consider in addition to my thoughts above- it would probably make the overall server implementation simpler and easier at the cost of more work in the main server thread.

Either way we take this, I am down to support the development and oversight of this project on a new branch of the repo (for example named asyncio-networking), as I have almost two years of prior asyncio experience developing complex Discord bots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementNew feature or requestNetworkingNetworking related issues and pull requests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions