Question

FINAL

Further testing revealed that in a newer version of G-WAN everything works as expected.

ORIGINAL I'm working with large files and G-WAN seems perfect for my use case, but I can't seem to wrap my head around streaming content to the client.

I would like to avoid buffered responses as memory will be consumed very fast.

Was it helpful?

Solution

source code is published now

Thanks. The value you got is obviously wrong and this is likely to come from a mismatch in the gwan.h file where the CLIENT_SOCKET enum is defined. Wait for the next release for a file in sync with the executable.

Note that, as explained below, you won't have to deal with CLIENT_SOCKET for streaming files - either local or remote files - as local files are served streamed by G-WAN and remote files will be better served using G-WAN's reverse proxy.

copying to disk and serve from gwan is inefficient, and buffering the file in memory is also inefficient

G-WAN, like Nginx and many others, is already using sendfile() so you don't have anything to do in order to "stream large files to the client".

I've looked at sendfile() but I couldn't find where gwan stores the client socket. I've tried to use CLIENT_SOCKET but it didn't work

The only way for CLIENT_SOCKET to fail to return the client socket is to use a gwan.h header that does not match the version of your gwan executable.

By using a G-WAN connection handler, you can bypass G-WAN's default behavior (I assume that's what you tried)... but again, that's unecessary as G-WAN already does what you are trying to achieve (as explained above).

This in mind, here are a few points regarding G-WAN and sendfile():

  • an old release of G-WAN accidentally disabled sendfile() - don't use it, make sure you are using a more recent release.

  • the April public release was too careful at closing connections, (slowing down non-keep-alived connections) and was using sendfile() only for files greater than a certain size.

  • more recent development releases are using sendfile() for all static files (by default, as it confused too many users, we have disabled caching which can be explicitly restored either globally, per-connection, or for a specific resource).

As a result, for large files test loads, G-WAN is now faster than all the other servers that we have tested.

We have also enormously reworked memory consumption to reach unparalleled levels (a small fraction of Nginx's memory consumption) - even with large files served with sendfile().

G-WAN at startup on a 6-Core Xeon takes 2.2 MB of RAM (without compiled and loaded scripts like servlets and handlers):

> Server 'gwan' process topology:
---------------------------------------------
  6] pid:4843 Thread
  5] pid:4842 Thread
  4] pid:4841 Thread
  3] pid:4840 Thread
  2] pid:4839 Thread
  1] pid:4838 Thread
  0] pid:4714 Process RAM: 2.19 MB
---------------------------------------------
Total 'gwan' server footprint: 2.19 MB

In contrast, Nginx with worker_connections 4096; eats 15.39 MB at startup:

> Server 'nginx' process topology:
---------------------------------------------
  6] pid:4703 Process RAM: 2.44 MB
  5] pid:4702 Process RAM: 2.44 MB
  4] pid:4701 Process RAM: 2.44 MB
  3] pid:4700 Process RAM: 2.44 MB
  2] pid:4699 Process RAM: 2.44 MB
  1] pid:4698 Process RAM: 2.44 MB
  0] pid:4697 Process RAM: 0.77 MB
---------------------------------------------
Total 'nginx' server footprint: 15.39 MB

And, unlike, Nginx, G-WAN can handle more than 1 million of concurrent connections without reserving the memory upfront (nor any configuration by the way).

If you configure Nginx with worker_connections 1000000; then you have:

> Server 'nginx' process topology:
---------------------------------------------
  6] pid:4568 Process RAM: 374.71 MB
  5] pid:4567 Process RAM: 374.71 MB
  4] pid:4566 Process RAM: 374.71 MB
  3] pid:4565 Process RAM: 374.71 MB
  2] pid:4564 Process RAM: 374.71 MB
  1] pid:4563 Process RAM: 374.71 MB
  0] pid:4562 Process RAM: 0.77 MB
---------------------------------------------
Total 'nginx' server footprint: 2249.05 MB

Nginx is eating 2.2 GB of RAM even before receiving any connection!

Under the same scenario, G-WAN needs only 2.2 MB of RAM (1024x less).

And G-WAN is now faster than Nginx for large files.

I want to stream large files from a remote source

sendfile() might not be what you are looking for as you state: "I want to stream large files from a remote source".

Here, if I correctly understand your question, you would like to RELAY large files from a remote repository, using G-WAN as a reverse-proxy, which is a totally different game (as opposed to serving local files).

The latest G-WAN development release has a generic TCP reverse-proxy feature which can be personalized with a G-WAN connection handler.

But in your case, you would just need a blind relay (without traffic rewrite) to go as fast as possible instead of allowing you to filter and alter the backend server replies.

The splice() syscall mentionned by Griffin is the (zero-copy) way to go - and G-WAN's (efficient event-based and multi-threaded) achitecture will do marvels - especially with its low RAM usage.

G-WAN can do this in a future release (this is simpler than altering the traffic), but that's a pretty vertical application as opposed to G-WAN's primary target which is to let Web/Cloud developers write applications.

Anyway, if you need this level of efficiency, G-WAN can help to reach new levels of performance. Contact us at G-WAN's website.

OTHER TIPS

There is a nice example of the require functionality, also included with gwan application.

http://gwan.com/source/comet.c

Hope this helps.

I think you probably mean http streaming, not comet - in this case, there is a flv.c connection handler example provided with gwan. Also, you can use c sendfile() for zero copy transfering of files, or splice() syscall depending on what you need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top