Skip to content
Aaronontheweb edited this page Nov 29, 2012 · 6 revisions

Hircine is a stand-alone RavenDB index builder used in continuous integration systems and automated deployments. Think of it like FluentMigrations, but for RavenDB indexes instead of SQL schemas.

Index building for RavenDB is a process that doesn't scale well traditionally because it's a blocking operation that happens on application startup typically.

If you have more than one RavenDB server or a large number of indexes you need to build, imagine just how long this could cause your ASP.NET app to spin while it executes Global.asax the first time!

Hircine solves this problem by moving the index building process to build time - that way your application's startup time and the state of RavenDB's indexes are fully decoupled from each other.

How Hircine Works

Hircine's goal is to give you a simple, fast solution for building RavenDB indexes on your servers independently of the execution of your application.

You'll be amazed at how much better your ASP.NET application performs when it doesn't try to build all of its indexes from Global.asax!

How RavenDB Indexes Are Built by the RavenDB Client

RavenDB indexes are C# classes which derive from Raven's AbstractIndexCreationTask object.

When the RavenDB client builds indexes on your remote server what it's really doing is taking instances of your index classes and serializes them over HTTP into a format that the remote RavenDB server can use to define a searchable / sortable index internally.

Most people typically use this method of the RavenDB client to build all of their indexes at once:

Raven.Client.Indexes.IndexCreation.CreateIndexes(typeof(SimpleIndex).Assembly, documentStore);

Where SimpleIndex is a type derived from AbstractIndexCreationTask and documentStore is an initialized IDocumentStore instance connecting to a live RavenDB database.

When this method is called, Raven iterates over all of the classes defined in SimpleIndex's assembly and creates instances of every type that is assignable from AbstractIndexCreationTask - once it has that full list of indexes, it synchronously builds those indexes against the IDocumentStore instance, which can be really slow and can even fail sometimes.

This is how RavenDB indexes are typically built and it's not an optimal solution. So let's see what Hircine does differently.

How RavenDB Indexes Are Built by Hircine

Hircine does things a little differently, but let's talk about what it has in common with the RavenDB Client approach:

  • Hircine also looks for index definitions contained inside user-defined .NET / C# assemblies.
  • Hircine uses the same method (ExecuteIndex) as the RavenDB client for building each individual index, so the instructions being sent to the RavenDB server are consistent with what the RavenDB Client does.

So what does Hircine do differently?

  • Hircine runs in its own stand-alone executable (hircine.exe), rather than inside your application.
  • Hircine can builds all of its indexes in parallel by default, using multiple HTTP requests and threads to get the job done faster.
  • Hircine can build indexes found in multiple user defined assemblies at the same time, rather than relying on successive calls to IndexCreation.CreateIndexes.
  • Hircine can build indexes against multiple RavenDB servers in parallel, rather than doing them one at a time like the RavenDB client.
  • Hircine works asynchronously against both remote databases and embedded ones for rapid testing.

From this set of behaviors, you start to appreciate Hircine's goals:

  1. To fully decouple RavenDB index-building from application startup;
  2. To make it trivial and painless to build indexes from multiple assemblies against multiple servers;
  3. To make the process of index building really, really fast; and
  4. To provide a simple interface that developers can integrate into their own build or continuous integration processes.

Installing Hircine And Dependencies

You'll need NuGet on your system in order to install Hircine. It'll also make life tremendously easier for you if you add NuGet.exe to your system's PATH variable.

Hircine installs as an executable and includes everything needed to run an embedded RavenDB database along with it, so you're best off installing it into its own directory via the NuGet command line:

C:\Repositories> nuget install Hircine -OutputDirectory hircine-runner
Successfully installed 'Hircine 0.1.1.0'.
C:\Repositories> cd hircine-runner
C:\Repositories\hircine-runner> ls

Directory: C:\Repositories\hircine-runner

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          9/2/2012  10:36 PM            Hircine.0.1.1.0

C:\Repositories\hircine-runner>

Note: the NuGet command line is different that the Package Manager Console in Visual Studio. You're better off not relying on PMC for Hircine given that it's not an assembly you're incorporating directly into a .NET project (although you can install Hircine.Core if you want to call it directly from your code!)

See the NuGet.exe command line reference if you need more information on how to use NuGet.exe.

Using Hircine

Once you've installed Hircine, you'll find that hircine.exe has a really simple interface that is easy to understand and appreciate.

Here's a simple example from the Hircine project itself:

c:\hircine> hircene.exe -e -a "C:\hircine\tests\Hircine.TestIndexes\bin\Relese\Hircine.TestIndexes.dll"
Hircine v0.1.1.0
Developed by the fine folks at MarkedUp (http://markedup.com/) - Apache License v2.0

Validating assemblies...
Loaded all (1) assemblies and was able to find indexes inside all of them.

Validating RavenDB connections...
Was able to connect to all (1) RavenDB instances successfully.

Starting index-building job...

Able to successfully build index BlogPostsByAuthor in server memory #2808346

Able to successfully build index WordCountPerAuthor in server memory #2808346

Able to successfully build index TotalPostingActivityByEmail in server memory #2808346

Success

So what did this example do? Let's take a look at Hircine's command line options to find out!

Hircine Command Line Interface

Required Properties

  • -a|assembly [ASSEMBLY_PATH] - A path to an assembly which contains RavenDB indexes. If you need to load multiple assemblies then you can call -a for each assembly. Paths can be relative or absolute. You must have at least one -a call or Hircine will not run.

  • -e|embedded - Use an embedded database. If you want to do a dry run with some RavenDB indexes, building them against an in-memory embedded database is a cheap and easy way to test.

  • -c|connectionstr [CONNECTION_STRING] - A RavenDB connection string to an out-of-process server (can be remote or even on the same machine; just needs to be accessible via HTTP.) If you need to be able to build indexes against multiple servers, then you can call -c once for each server.

NOTE: You must call either -e or -c at least once in a Hircine call or Hircine will not run the job. If you call both -e and -c, the -e call takes precedent and Hircine won't attempt to build any indexes against the servers specified in each -c call.

Optional Properties

  • -s|sequential - When building indexes against multiple database servers, execute the jobs sequentially. In case you're worried about a high-risk indexing job (not that any exist, as far as I am aware) this will ensure that Hircine will not build any additional indexes if a job fails against any of the databases specified in each -c call.

  • -p|pauseindexing - If the -s (sequential) flag is set, this flag will tell Hircine to pause indexing on the remote server while it builds indexes, and it will resume indexing on the server once all of the indexes have been updated. This is a necessity on high-volume servers when updating indexes that are almost always stale under production loads.

  • -f|continueonfailure - If the -s flag is already set, this flag will tell Hircine to keep building indexes (sequentially) even if there are failures.

  • -n|nossl - If you attempt to transmit username / password credentials via RavenDB without having an SSL connection, Raven will throw errors. By setting the `-n- flag you acknowledge that you want to suppress those errors and continue the job anyway despite doing something potentially insecure.

Hircine Help

If want to see the explicit options for Hircine, just run:

c:\> hircine --help