Version 6.3.1 of The Server Framework was released today.
This release is purely a bug fix release and includes the following fixes.
Fixes to JetByteTools::OpenSSL::CStreamSocketConnectionFilter to prevent buffer reference leaks which result in memory leaks during secure connection processing; see here for more details. Fixes to JetByteTools::OpenSSL::CAsyncConnector to prevent socket reference leaks in situations where connections are reset or where unexpected SSL errors occur. These socket reference leaks can cause delays and hangs when shutting down a server or connection manager.
I’ve had one of those days. In fact I’ve had one of those days for a couple of days this week…
It started when I decided to improve the profiling that I was doing on a new memory allocator for The Server Framework by extending the perfmon and WinRS based distributed server testing that I wrote about a while back. This allows me to create a set of perfmon logs, start a server to collect data about and then start a remote client to stress the server.
See here for details.
There’s a bug in the OpenSSL stream socket filter which results in I/O buffers being leaked on both inbound and outbound data flow. This causes the memory used by the client or server to grow throughout the life of the process. The bug has been present since release 6.2 when the structure of the filtering code was redesigned.
Note that due to the fact that the filtering code was all redone at that time I expect that the same bug is likely to be present in the SChannel, SSPI and compression filters.
As I mentioned last time, supporting a large number of concurrent connections on a modern Windows operating system is reasonably straight forward if you get your initial design right; use an I/O Completion Port based design, minimise context switches, data copies and memory allocation and avoid lock contention… The Server Framework gives you this as a starting point and you can often use one of the many, complete and fully functionaly, real world example servers to provide you with a whole server shell, complete with easy performance monitoring and SSL security, where you simply have to fill in your business logic.
Using a modern Windows operating system it’s pretty easy to build a server system that can support many thousands of connections if you design the system to use the correct Windows APIs. The key to server scalability is to always keep in mind the Four Horsemen of Poor Performance as described by Jeff Darcy in his document on High Performance Server Architecture. These are:
Data copies Context switches Memory allocation Lock contention I’ll look at context switches first, as IMHO this is where outdated designs often rear their head first.
As you’ve seen from some of the earlier tutorials, WASP has quite a few command line parameters that can change how it runs. You can run WASP as a normal executable or install it as a Windows Service. The complete set of command line options are displayed if you run WASP with /help or with an option that it doesn’t understand but I thought I’d list them all here for completeness and so that I can explain in a little more detail what each one does.
So far the tutorials have focused on a simple length prefixed message type. This is probably the easiest message in the world to process, the message framing is very simple and there’s hardly anything to do in your message framing DLL. Unfortunately not all protocols are this simple to parse. Another common real-world protocol is a line based protocol that is delimited by a terminating character, or characters. One such protocol is the POP3 protocol which works in terms of commands which are delimited by the CR LF sequence.
As you have discovered if you’ve been following the tutorials, WASP is configured using an XML file.
This file can either live in the same directory as the WASP executable or, for when you’re running WASP as a Windows Service, it can live in a place that is configured in the registry.
The file is pretty simple and we’ve covered most of the options in the various tutorials but there are some configuration options that we haven’t touched on yet and it seems sensible to have one place to look for details of all of the options that you can configure in the config file.
By now you’ve probably taken a look inside of the WASP SDK header, WASPDLLEntryPoints.h and seen all of the various plugin entry points that you can export from your plugin. This tutorial will explain what each of them is for and how you use them and will present a simple plugin which uses all of the entry points and logs its actions to WASP’s debug log.
As you’ve seen from the previous tutorials, a WASP plugin can be either a message framing DLL or a message handling DLL or both depending on the entry points that it exports.