Have you ever wondered how the GeoMedia engine works in GeoMedia WebMap to serve high-quality maps quickly? Map Server and its companion, Map Server Manager, work together to give you both.
The Map Server of GeoMedia WebMap is a key architectural part of the product. It uses a subset of the GeoMedia Desktop engine so that it can be used in a server environment. In essence, this is a headless version of GeoMedia Desktop with some additional façade which makes it easy for clients (like a WMS) to generate the required outputs. GeoMedia Desktop is mostly a single-threaded application which is used by a single user at a time. In a server environment we expect that multiple users need to be handled simultaneously. That’s why we use a process farm (or pool) of Map Servers. Here’s where the Map Server Manager comes into play. Its role is to maintain a pool of Map Servers and give handles to them out on request to the client that wants to use it. The maintaining part means that it ensures each Map Server’s health by looking at specific parameters of the process. The handing out handles means that whenever a Map Server is idle and there is some work to do it is given out to the client app.
A Little History
The original Map Server Manager was actually quite a solid piece of software that didn’t require much change since we first wrote it. When set up right, it just worked. What’s most interesting about the original implementation is that it used an ingenious combination of synchronous and asynchronous coding techniques. When a Map Server request came in, the list of handles was immediately examined to find whether any of the Map Servers were idling at the moment. If it was, the handle was returned. Otherwise, the request was put into a queue waiting for a Map Server to turn idle. On top of that, this handled the approach where the client can request the Map Server by a MSS file and preferentially selected the proper Map Server.
Even though this internal design was very efficient, it made it very hard to augment the logic with new features. We took great care to avoid deadlocks and race conditions between the synchronous and asynchronous parts of handling a Map Server request. That’s when we made the decision …
We’re Rewriting the Map Server Manager
Sometimes it is a good idea to freshen up the code and the way blocks of it interact. When talking about such a crucial part of software which centralizes the whole functionality, it is not an easy decision, though. We needed a full understanding of the inner working and behavior first.
The new Map Server Manager needed to have good boundaries set up between parts of different responsibilities while still retaining its high throughput. After several iterations, the inner mechanism is now fully asynchronous:
- Each request for a Map Server opens in a new thread and places the request as an item in the queue
- The requester thread then waits on completion of the order for a Map Server
- There is another thread whose sole purpose is to look through the request queue and match them against the list of idling Map Servers, trying to get the best match, by:
- Rotating the usage of Map Servers
- Trying to match any session requests against Map Servers already responsible for it
- When a request is matched to an idling Map Server, it is handed over for completion to yet another thread running an object that is looking after the Map Server handle
- The Map Server handle object checks up on the health of the Map Server handle and if it’s ok, it signals the requester thread that its order has been fulfilled and passes the handle to the Map Server object
- The Map Server handle object then awaits the release of the Map Server object, periodically checking whether everything is still ok with the process health-wise
- When the Map Server object is released, the Map Server handle object does a final health check, possibly clearing the Map Server if that’s needed (memory threshold is breached and similar) and signals that it is ready for another turn
And all of this happens simultaneously handling multiple concurrent requests.
So, here are the broad components taking part in the whole process:
- Map Server Manager object serving the request in a “get server” call
- Request queue and its thread
- Map Server pool
- Map Server handle object and its thread
On top of that, there is another helper thread running in the background which cleans up the GWMLog and GWMCache folders of stale items.
The new architecture of the Map Server Manager has allowed us to easily add a new health check on the Map Server processes and doesn’t compromise any performance. Actually, our tests show a slight increase in throughput due to the use of new light-weight synchronization primitives that were introduced in the recent versions of Windows. These are the user-mode critical section and user-mode condition variable. The new health check now also monitors the size of virtual memory any given Map Server process is occupying. Since it is limited, and might not all be committed bytes (those that count towards the page file size) it still may result in an out-of-memory condition. The rewritten Map Server Manager does all of the health checkups more frequently and can react faster to any problems it detects.
For more information about GeoMedia WebMap, read the Product Release Details.