Saturday, December 31, 2011

Open Source Shines - RavenDB on Linux

In the previous article, I wrote about RavenDB - a .Net NoSQL Document Oriented Database that supports Transactions - and why I had decided to spend time on it to get it to run under Linux. Now RavenDB was created for a Windows only audience and the creator's website doesn't not provide any guidelines about how to implement it under Linux.

After numerous attempts and with some modifications to the source code, I was able to get it to run under Linux. Some features that are not available under Linux as they are under Windows such as the web based UI - Raven Studio . However, dynamic index functionality also did not seem to work under Linux for some reason.

In my initial review had failed to notice something. When the server application starts at command line, you have a few options such as garbage collect, clear screen, and reset. When I had fired the test application that I had created, I noticed and then did not pay any attention to the fact that the server was not sending responses to all of the calls that were being sent by the client. When this happened, the client froze until either I issued a reset command to the server command line, or the connection timed out eventually. Since reset seemed to get the ball rolling for the moment, I was not too much concerned at that time.

The couple days ago, I decided to spend time to finish the task that I had started - to tweak RavenDB's code enough to get the database to fully work under Linux and then to use it in a project. My many efforts to identify the root cause of the issue were not at all fruitful. My first instinct was to review the server log files. There was nothing useful to be found there.

I thought that may be the document Id generator was causing the hold up so I provided manually generated Ids to my document objects. When that didn't solve the issue I started placing breakpoints all over the client library code and debugged the application one line at a time, stepping into every function call possible. I came across a piece of code that seemed like a promising lead.

It was in the Raven.Client.Lightweight project in the Connections/HttpJsonRequest.cs file at line 304.

var text = reader.ReadToEnd();

When control reached that statement, the execution froze until I issued the reset command at the server command line. It meant only one thing - there had to be a corresponding response writing activity on the server. I reviewed the code couple lines above to get some clues. I evaluated response object on line 299 for its ResponseUri property.

ResponseHeaders = response.Headers;

The ResponseUri property was set to "http://localhost:8080/bulk_docs".

At the same time the server had the following output on the terminal:


That was my clue. I needed to locate a responder that handled the "bulk_docs" url.
Raven.Database project has a responder that handles "bulk_docs" under Server/Responders/DocumentBatch.cs. On setting breakpoint in the file on line 38 and following the control line by line lead me to Server/HttpServer.cs on line 318 which always ended in exception with a not so meaningful error message and once this method was executed the control stop.


I debugged further into the FinalizeRequestProcessing which led me to line 351.

ctx.FinalizeResonse();

This took me to Server/Abstractions/HttpListenerContextAdapter.cs line 82. The control disappeared once I tried to step further than like 86.

ResponseInternal.OutputStream.Flush();

I put a breakpoint in the catch block and sure enough there was an exception - and I/O exception of some sort - which was not handled. Couple lines below was the smoking gun. Line 88 never executed in event of an exception and that would be what was causing the server to hang on to request.

ctx.Response.Close();

I made a slight tweak to this file and moved the two lines into the finally block.


I recompiled the server and there it was. RavenDB was not longer freezing on individual requests and dynamic indices were working as designed. RavenDB on Linux is now ready to be used in application development. Since RavenDB was created as an Open Source application, it was possible to review the code and troubleshoot this issue. The issue seems to not affect Windows as RavenDB is being used by real world businesses.

Next thing to do would be to create a non WPF replacement for Raven Studio for use in Linux.


This article is part of the series NoSQL - RavenDB on Linux. The series contains the following articles:
NoSQL - RavenDB on Linux
Open Source Shines - RavenDB on Linux
RavenDB on Linux - Source Code
RavenDB on Linux - Update

2 comments:

  1. Karim,
    Mind, you can use the Raven Studio on Linux using Moonlight.

    ReplyDelete
  2. I understand that Ayende.
    However, due to Silverlight dependencies, the project doesn't compile under Linux. At least not under my 64 bit Ubuntu 11.10 setup with Mono 2.10.5.

    Mono JIT compiler version 2.10.5 (Debian 2.10.5-1)

    ReplyDelete