-
Notifications
You must be signed in to change notification settings - Fork 166
Description
As you may know, we are implementing a fully featured WMS server based on Node Mapnik. It turns out, that most of Mapnik's incredible rendering speed, compared to many other WMS servers, has only little effect with slow network connections. For example, many typical map requests are served about 1.5 to 2.5 times faster than by GeoServer on a local 1 GB network (not to mention localhost requests). However, this factor tends to fall to 1.0 or even 0.8 on typical Internet links.
One reason may be the missing ability to implement chunked
HTTP Transfer-Encoding as GeoServer does. Here, the final map image is encoded to, for example, PNG format in chunks. Each chunk is sent down the wire as soon as it is available. With Node Mapnik, the whole rendered image is encoded into one single chunk by one of the save_to_string
methods. So, with GeoServer, there is a level of parallelism by overlapping image encoding and sending, which actually brings some extra speed compared to our implementation.
So, I'm asking for a new encodeChunked
method for the Node Mapnik Image
object. Likely the simplest implementation works with a callback function that gets called for each chunk available. Typically, one would specify the desired chunk size as an argument when the function is called. The callback function gets invoked once for each chunk, which is passed as a Node.js Buffer
object. Additionally, a boolean flag last_chunk
is required to signal which one is the last chunk.
Since I'm no C++ expert, I currently have no idea how to implement this on the C++ side. This seems to require a stream/buffer, that triggers an event/callback after N bytes have been written to the stream. Maybe there is some Boost template for that? Also, I have no idea whether it's better to implement this as a sync or async method (from a performance point of view), since for each chunk some (expensive?) inter-thread access seems to be required. Actually, this new method could as well be encodeChunkedSync
.
On the Javascript side this could simply look like (heavily shortened):
// encode and send image in 512 byte chunks
myImage.encodeChunked(512, function(err, buffer, last_chunk) {
response.write(buffer);
if (last_chunk) {
response.end();
}
}();