Strelka (Стрелка)

home

deveiate.org/projects/Strelka

code

bitbucket.org/ged/Strelka

github

github.com/ged/strelka

docs

deveiate.org/code/strelka

Description

Strelka is a framework for creating and deploying Mongrel2 web applications in Ruby.

It's named after a lesser known Russian cosmonaut who was one of the first canine space travelers to orbit the Earth and return alive. Her name means “little arrow”.

Prerequisites

Installation

$ gem install strelka

Getting Started

We're going to assume you've already built and installed the Mongrel2 daemon. If not, please refer to the Mongrel2 documentation and get that ready.

Mongrel2 loads its configuration from a SQLite database. You can create the this database in any fashion you like, but the Mongrel2 ruby module includes a command-line tool called m2sh.rb that'll let you quickstart a server if you just want to experiment. If you've already installed the strelka gem, then it will already have been installed as a dependency.

To bootstrap a basic server, configure it, and run it:

$ mkdir strelka-tryout
$ cd !$
$ m2sh.rb quickstart

This will generate a Ruby DSL config, then invoke an editor on it.

Make sure the config has a line like:

route '/hello', handler( 'tcp://127.0.0.1:9999',  'helloworld' )

in the 'host' section; that's the part of the Mongrel2 server we'll be talking to.

The quickstart will generate a SQLite configuration database for use with Mongrel2 in your current working directory, with the default required directory structure. Mongrel2 will listen on port 8113 (unless you changed it), and send all requests starting at the URI /hello to a handler called helloworld.

If you stop the server (Ctrl-C will do so), you can restart it like so:

$ m2sh.rb start

Now that the Mongrel2 daemon is up and running, we can move forward and create our first application!

A Minimal Application

Strelka applications are subclasses of the Strelka::App class. Strelka::App is pretty minimal by itself; it inherits most of its behavior from the basic Mongrel2::Handler class, only adding a few convenience methods for common HTTP tasks.

A minimal application would look something like:

#!/usr/bin/env ruby

require 'strelka'

class HelloWorldApp < Strelka::App

    def handle_request( request )
        response = request.response
        response.content_type = 'text/plain'
        response.puts( "Hello, World!" )
        return response
    end

end # class HelloWorldApp

# Run the app
HelloWorldApp.run if __FILE__ == $0

While functional, this application is pretty dumb, and making it do anything more intelligent on your own would require a bunch of additional code and accompanying tests. Fortunately, Strelka already has done the heavy lifting. It knows how to read the Mongrel2 configuration and hook your app up with the right sockets to talk to the Mongrel2 front end (providing you follow one of several simple conventions), provides hooks into the lifecycle of an HTTP request, and includes a plugin system that uses these hooks to handle common application tasks. This allows you to mix in the specific framework parts you need, so you get exactly what you want and nothing more.

Talking to Mongrel2

Mongrel2 associates handlers with itself via an identifier, which is described in the Mongrel2 manual as a UUID, but can actually be any string consisting of dashes and alphanumeric characters. Strelka reads the Mongrel2 config database, and can automatically configure its apps to talk to the right socket with the right send_ident if it can find them. It gives you a couple of different ways of doing this. It will default to a string derived from the name of the class, or you can set it yourself by declaring an ID constant in your application class. If you need more control, you can also override the ::run class method and super with the right appid:

class HelloWorldApp
    # Run as a tester if not running in the production environment
    def self::run
        appid = if Socket.gethostname.include?( 'test' )
                'helloworld-test'
            else
                'helloworld'
            end

        super( appid )
    end
end

Because our config.sqlite configuration directs requests to / to be sent to the helloworldapp handler, Strelka will automatically find and pair this route to Mongrel2 when run.

Run this handler, then point a browser to http://localhost:8080/. If you see the text “Hello, World!”, congrats! We'll build off of this in the next section, the Strelka Tutorial.

Packaging

If you want your app to be launchable via the strelka command, you can do so by registering it with the Strelka::Discovery module. For instance, if your app is defined in a file called lib/acme/store.rb and you want to start it with the command

strelka start acme-store

then you'd do something like:

require 'strelka/discovery'
Strelka::Discovery.register_app( 'acme-store', 'acme/store.rb' )

If you want the app to be launchable directory from the gem, you can put the above discovery code in a file named lib/strelka/apps.rb to your gem. The `strelka` command will load all of those files from any installed gems before running start. You can test to see which apps are discoverable this way using the strelka discover command.

See Strelka::Discovery for more info.

Further Reading

You'll likely want to start with the Tutorial.

Roadmap

Going forward, we're going to be extracting useful stuff out of our own applications as plugins, and finishing up the packaging and deployment stories once we've ironed out the details in own environment.

Here's a tentative list of what kinds of stuff we have planned:

More Plugins

New Application Styles

Create some new handler classes for different application styles, similar to those in the Tir framework.

Chunked Encoding

Support for sending partial responses via the Chunked encoding.

Contributing

You can check out the current development source with Mercurial via its project page. Or if you prefer Git, via its Github mirror.

After checking out the source, run:

$ rake newb

This task will install any missing dependencies, run the tests/specs, and generate the API documentation.

License

Copyright © 2011-2016, Michael Granger and Mahlon E. Smith All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.