Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Tuesday, February 14, 2012

VCL Random url part

Random is random, usually. Unless it's being fetched every 20th minute and included as a part of a site with heavy traffic. That's a lesson I learned the hard way by relying on an ad networks RSS aggregator that included one of our RSS feeds on it's pages. The feed is randomized on our end with a list of nodes that are straight out of Views via some custom theming. The nodes are grouped in threes from a larger set.

What I noticed was that over 24 hours, what should have been an even distribution turned out to be heavily weighted towards one specific set. The ad networks RSS aggregation ran on a schedule and as bad luck would have it, Views liked to display the same set every time the RSS aggregator made a visit. Probably just bad luck but to the customer it looked like one set of nodes were favored over the others.

As I run Varnish for caching I started thinking about if I could do this in another way. I thought about faux round-robin directors and complicated solutions involving dns aliases and htaccess rewrites.

Then I stumbled upon this blogpost by Chris Davies who is just generally speaking one of the most knowledgeable techies I know of. So enter inline-C for my VCL.

sub vcl_recv{
    if (req.url == "/randomizeme") {
C{
char buff[5];
sprintf(buff, "%d", rand()%4+1);
VRT_SetHdr(sp, HDR_REQ, "\017X-Distribution:", buff, vrt_magic_string_end);
}C
        set req.url = "/randomizeme/" req.http.X-Distribution;
    }
 }

It works like this:
- Varnish picks up the request on url /randomizeme
- Varnish executes the inline C
- Varnish sets a special header with the randomized integer (the header works as a variable)
- Varnish then rewrites the url to /randomizeme/1-4
- Varnish finally fetches the above url from the backend which is rigged to display different content depending on which "slot" is chosen.
- Varnish delivers the randomized content to the visitor/aggregator/whatever

A little warning: If you modify the header name "X-Distribution", note that the "\017" must be updated, it's octal for the length of the string. I forget if it should include the ":" or not. Trial and error, watch that log for segfaults!