Halcyon

Notice: The website is currently being udpated. Sorry for any inconvenience.

Configuration

There are a great deal of configuration points in your application, including
but not limited to the config/config.yml settings file.

config/config.yml

This file often starts like this:

 1 ---
 2 ## config/config.yml
 3 # = Framework
 4 # 
 5 allow_from: all
 6 
 7 # = Environment
 8 # 
 9 # environment: production
10 
11 # = Logging
12 # 
13 logging:
14   type: Logger
15   # file: # STDOUT
16   level: debug
17 
18 # = Application
19 # 
20 # Your application-specific configuration options here.

(Extra comments have been removed for the sake of brevity.)

In this file you can specify whether your application allows requests to come
from clients locally (only requests from @localhost@), from Halcyon clients
(ignoring any non-Halcyon client), or all (which is the default).

You can also explicitly specify which environment to run under and how to log
messages, including where to save the logged messages and what level to save.
Read more about configuring logging.

Boot/Initialization

The boot process also provides a great way to customize your application,
including adding in dependencies and wiring in new functionality.
Initialization is handled by the files in config/init/ such as requires.rb
and routes.rb etc.

Let’s take a look at each file.

Requires

The file config/init/requires.rb includes any necessary dependencies for your
application, including your preferred ORM library and anything else necessary
to your application’s operation.

By default, the requires init file is empty, requiring nothing. This is what it
should look like for a freshly created app:

1 %w().each{|dep|require dep}

If you’re not familiar with the syntax used here, this is simply another way to
define an array of strings and require each entry as its own dependency. The
following code snippets are identical and are both valid code for the
requires.rb file:

1 %w(sequel drb).each{|dep|require dep}
2 
3 ## OR
4 
5 require 'sequel'
6 require 'drb'

Initially it may seem like more code, but for longer lists of dependencies, it
can save a lot of repetition.

Environment

The file config/init/environment.rb shouldn’t require a great deal of change
since it simply wires Halcyon.environment to the
Halcyon.config[:environment] configuration value and sets the default value
if not set already.

However, feel free to alter this and any file at will (so long as you know what
you’re doing, and sometimes even when you don’t).

Routes

The file config/init/routes.rb contains the definition of the routes. There
is an in-depth article going over routes with plenty of
links to further documentation.

Hooks

The file config/init/hooks.rb contains the definition of the startup,
shutdown, and any other hooks available. This allows you to run some setup or
shutdown tasks to be run after the configuration and all other dependencies
have been loaded. This is ideal for connecting to databases or opening other
resources necessary for the operation of your application.

You can see where in the boot process the hooks are run by starting a brand new
Halcyon application and then shutting it down. Look for notifications for where
to define startup and shutdown hooks, this is when the code is run.

config/init/*.rb

Other files in the init folder are also run during boot so you can put any
Ruby file in there and it will be run at boot. For example, a database.rb
file is certainly appropriate to setup database configuration values, etc.

Rack and runner.ru

The last point of customization exists between the application itself and the
server running it through Rack. Since Halcyon is a
simple Rack application and Rack applications can be layered, it’s perfectly
acceptable to layer in static file serving (for development only, stick to
something faster like Nginx or Apache for production) or for handling file
uploads or other really-long-running processes (until we wire in the deferrable
actions which spawn off as their own threads where necessary like Merb).

There are also several standard Rack middleware available such as
Cascade which finds
the first application in an array of applications (such as a Halcyon app
followed by a Rails app) to return a non-404 response, or the Reloader
middleware which reloads changed classes if changed between requests. There are
still more interesting middleware available.

Here’s a sample runner.ru file used by one of the example applications
distributed with Halcyon’s source:

 1 require 'halcyon'
 2 
 3 $:.unshift(Halcyon.root/'lib')
 4 puts "(Starting in #{Halcyon.root})"
 5 Thin::Logging.silent = true if defined? Thin
 6 
 7 # = Apps
 8 # The applications to try.
 9 apps = []
10 
11 # = Redirecter
12 # Requests to <tt>/</tt> get redirected to <tt>/index.html</tt>.
13 apps << lambda do |env|
14   case env['PATH_INFO']
15   when '/'
16     puts " ~ Redirecting to /index.html"
17     [302, {'Location' => '/index.html'}, ""]
18   else
19     [404, {}, ""]
20   end
21 end
22 
23 # = Static Server
24 # Make sure that the static resources are accessible from the same address so
25 # we don't have to worry about the Same Origin stuff.
26 apps << Rack::File.new(Halcyon.root/'static')
27 
28 # = Halcyon App
29 apps << Halcyon::Runner.new
30 
31 # = Server
32 # Run the Cascading server
33 run Rack::Cascade.new(apps)

This will serve static files necessary for running the application, passing
through non-matches to the actual Halcyon application.