User:Epyon/2010/TpServerCppAsio
From Thousand Parsec Wiki
Contents |
Abstract
The following project has two major goals -- the primary goal is moving tpserver-cpp network layer into the Boost.ASIO framework, and preparing the rest of the server for taking advantage of the Proactor architecture that is weaved into ASIO. The secondary goal is to take advantage of the new architecture to rewrite the tpserver-cpp systems to be asynchronous, basing on ASIO's framework.
Extended abstract
boost::asio is the current cutting edge of C++ server development. Not only is it capable of running high performance servers on absurd load, it is also a very readable, portable and easily extendable framework for server development, and a candidate for inclusion in the standard library for the next C++ standard.
Moving tpserver-cpp to boost::asio would have several advantages:
- First of all an asynchronous model of operation would emerge, allowing to make the whole server act completely asynchronously in the future, allowing to take full advantage of modern hardware (multithreading, multicore) -- what would definitively increase the servers scalability, responsiveness and ability to handle multiple clients effectively.
- Secondly, that would allow for a much cleaner (and tested!) implementation of the network layer.
- Finally tpserver-cpp network layer would become platform independent, using asio would remove the dependency on quite a few platform specific libraries.
Project goals
Primary goal
- substitute tpserver-cpp network layer and connection classes with boost::asio code, on a single thread and single Proactor instance
Secondary goals
- enforcing the player/server data distinction as discussed below
- refactor the code on the go with threading in mind (logging, etc)
Bonus goals
- full multi-threaded architecture of the system, based on boost::strands
- try a cut down (without some additional features) compilation on native Windows
Implementation details
Doing last years project i definitively underestimated the amount of work for a transition to boost::asio, also I didn't have much experience with ASIO itself. Now I know both ASIO better, as well as tpsever-cpp's internal structure. The amount of changes needed, especially if we want to support threading, is enormous.
Porting to ASIO's networking model
The major goal is to take advantage of ASIO's network layer -- without thinking about threading in the beginning. This will need a rework of the Connection classes and of course mainly the Net class. The change wont be as smooth though, because several other features depend on the current network model. Timers will need to be implemented using ASIO's proactor as events (what in itself is a good thing indeed), also the metaserver connection and handling will need an overhaul. SSL handling on the other hand will be a lot simplified (although ASIO internally uses OpenSSL, it does a great job of hiding OpenSSL's ugly API). I've still no idea what to do with Avahi though.
Threading
Once that is done and tested as working the harder part will begin -- thread safety. It's no secret that tpserver-cpp is completely unsafe from threading point of view. However, deeper research revealed that with a proper design, there's no need for mutexing altogether -- to provide full thread support we just need to provide the following:
- ruleset and game data is read only during the turn duration (persistence will be called only once for every requested item)
- players modify only their own dataset (their order queue, which doesn't modify the ruleset/game state)
- once turn end comes, the server locks against player requests and performs a synchronous update of the game state
As we see, in this "ideal" example, we will only have asynchronous reads, not writes, and we can set up a guarantee that the read data will not change. Hence the second part of the project will be about setting up and enforcing those guarantees where possible -- some problems will still occur however, like the logging system that needs to be done in a single thread.
Project schedule
I'll be available probably 4/5 time during the coding period (I need some time for my PhD). Also 10-12 days will probably be spent on a short vacation, although I might still be able to do some work then.
May 10 - May 23 (pre-planning)
Getting up to date with the server, and investigating the internals with ASIO in mind -- so coding can start immediately at May 10. Furthermore, fixing a few leftovers from last year that may prove a problem for ASIO (no pointers may be left in code).
May 24 - July 12 (phase 1)
- implementing the single-thread proactor of ASIO as the network layer
- rewriting the connection classes and network class to handle that (using strands)
- reimplementing all the timer events as proactor events
- fixing smaller threading issues on the go
July 13 - August 9 (phase 2)
- rewriting code for the full server and player data separation
- preparing the end of turn modification lock
- rewriting the thread unsafe systems in a thread-safe manner (logging, etc)
- rewrite of the persistence module to keep up with our guarantees (also checking on the threading of the SQL connection)
- any bonus goals if time left
August 9 - August 16 (buffer)
This week is purposefully left out as buffer time.
