The current metaserver has room for some improvements. The biggest right now is that there is a single metaserver (thus single point of failure). It also doesn't record all the information that would be useful.
Currently, the metaserver records this information:
Proposal for improvements:
Making it a web based service (cgi-bin script or php script) is a good way to go. The web server deals with running multiple copies at the same time - thus, we don't care as much about timeouts in resolving the host name (one of the scripts running on the server may take a while to complete, but that doesn't cause problems as other scripts can run). Web based script access is also quite common, which means that it would be much easier to get multiple instances up compared to requiring a custom program to be run.
While overkill, tying it into a mysql database on the back end takes care of file locking/contention issues. A secondary table could be used to blacklist certain servers, typically those that are misconfigured.
There would be 3 scripts to handle this:
Script 1 could be done relatively simply by passing values in the URL - http://metaserver?sc_version=aaaa&players=3&etc. But probably better to use an http request library, and use post submits - means we don't need to do lots of escaping by passing something as a URL.
Scripts 2 & 3 are relatively simple - they basically just dump the data from the mysql database. For the client script, it could be handly for it to include some demarcation line, like '— Metaserver Info Start —' so that the client doesn't have to be able to fully parse http - it just needs enough to make a request and look for that, knowing anything that follows it is the information it wants. But if it also uses a http request library, that should provide necessary parsing logic.
The server component is the hardest part. Since HTTP is tcp connections, these can time out, may take some time to make the connection, etc. Simplest way short term would be to have a seperate process that is started (perhaps through popen) that the server talks to, and that other process updates the metaservers. In a sense, it acts as a proxy, but so long as the popen is done with non blocking IO, never any danger of things getting frozen on the server. That proxy would try to update all the metaservers it knows about, with some extra logic on what to do when a metaserver isn't responding. Alternatively, using threads may be a cleaner way to do this. The data that the metaserver thread would need is pretty limited, so would not need much in the way of locks (and in fact, a data structure just for the dynamic metaserver data could be created, with the server just locking that as it needs to update it, with perhaps the metaserver thread having its own copy that it periodically copies from the original, so that neither lock would need to be held for very long)
There shouldn't be any need for the metaservers to talk to each other. Since each server will try to talk to all the metaservers, there should be no need. The client will choose one of the metaservers from the list to use (at random), thus doing load balancing of a form. The preferred metaserver could also be set in the client. If the client can not connect to the first metaserver, it would try the next, etc.