Search code examples
asp.netc#-4.0redisbooksleeve

BookSleeve Wait() timeout in Razor page while benchmarking


I'm just beginning to mess around with BookSleeve (and redis) on Windows and just wanted to see if I could get some direction on what I may be doing wrong here. Using the following code, and then running ab against it, I can serve ~500 requests before w3wsvc.exe crashes. When I attach to the process to debug I see that the request to the redis server is timing out.

@using (var conn = new BookSleeve.RedisConnection("localhost"))
{        
    conn.Open();
    var catgrabber = conn.ListRange(0,"categories",0,-1);
    byte[][] categories = conn.Wait(catgrabber);
    foreach (byte[] category in categories)
    {
        <h3> @System.Text.UTF8Encoding.UTF8.GetString(category) </h3>
        var actgrabber = conn.ListRange(0, String.Format("activity:{0}",
            System.Text.UTF8Encoding.UTF8.GetString(category).Replace(' ', '_')), 0, -    1);
        byte[][] activities = conn.Wait(actgrabber);
        foreach (byte[] activity in activities)
        {
            <label for="@System.Text.UTF8Encoding.UTF8.GetString(category).Replace(' ', '_'):@System.Text.UTF8Encoding.UTF8.GetString(activity):12345">
            <input type="checkbox" id="@System.Text.UTF8Encoding.UTF8.GetString(category).Replace(' ', '_'):@System.Text.UTF8Encoding.UTF8.GetString(activity):12345" value="@System.Text.UTF8Encoding.UTF8.GetString(activity)"/>
            @System.Text.UTF8Encoding.UTF8.GetString(activity)
        </label><br />
        }
    }
}

I have not yet installed the .NET async/await CTP.

Now, for just a a single webpage hit this works great. I just wanted to bang on the server hosting this so I did ...

ab -n 1000 -c 5 http://server/page.cshtml

It'll serve the 500-700 requests and then crash. While I am not sure I'll ever have this kind of load, I believe that this indicates a glaring flaw in my code and would like to have someone smarter than I point out what I'm doing wrong.

Thanks!


Solution

  • The first thing I notice is that that code is way too complex to go in a razor view - it needs to be moved to the controller. That in itself probably isn't the problem though.

    The issue is probably the large number of connections being created that may not be fully cleaned up before the next one is loaded. From the BookSleeve site:

    A connection is thread-safe and (with the exception of Wait) non-blocking, so you can share the connection between as many callers as you need - this allows a web-site to make very effective use of just a single redis connection. Additionally, database-switching (the 12 in the examples above) is handled at the message level, so you don't need to issue separate SELECT commands - this allows multi-tenancy usage over a set of databases without having to synchronize operations.

    This means that you will probably get better results if you create one shared connection to process 1000 queries than if you create 1000 connections to process one query each.