Class: Shadow

Attributes

NameRead/write?
pid R

Public Class Methods


new (config, environment, name, address = '0.0.0.0', port = '2001', sleep = nil)

    # File lib/shadow.rb, line 10
10:   def initialize(config, environment, name, address = '0.0.0.0', port = '2001', sleep = nil)
11:     ActiveRecord::Base.establish_connection(YAML.load_file(config)[environment.to_s])
12:     ActiveRecord::Base.allow_concurrency = false # AR doesn't release connections fast enough
13:     @sleep = sleep
14:     @sync = Sync.new
15:     @pid = serve(self, name, address, port)
16:   end

Public Instance Methods


find (table, id)

Finds and returns an ActiveRecord instance (returns a new record if id is nil). Dynamically instantiates an ActiveRecord parent class for each call.

    # File lib/shadow.rb, line 47
47:   def find(table, id)
48:     klass = Class.new(ActiveRecord::Base) { self.table_name = table }
49:     id ? klass.find(id) : klass.new
50:   end

process (request, response)

Implement the mongrel event handler. Responds to all four HTTP methods.

    # File lib/shadow.rb, line 19
19:   def process(request, response)
20:     sleep(rand * @sleep) if @sleep
21:     table, id = request.params["PATH_INFO"].split("/")
22: 
23:     obj, code = nil, 200
24:     @sync.synchronize(:EX) do # sad
25:       begin
26:         obj = find(table, id)
27:         case request.params["REQUEST_METHOD"]
28:           when "PUT", "POST"
29:             obj.update_attributes(YAML.load(request.body.read))
30:             obj.save!
31:           when "DELETE"
32:             obj.destroy
33:         end
34:         obj = obj.attributes
35:       rescue Object => e
36:         obj, code = e.to_s, 400
37:       end
38:     end
39:     
40:     response.start(code) do |head, out|
41:       head["Content-Type"] = "text/yaml"
42:       out.write obj.to_yaml
43:     end
44:   end

serve (me, name, address, port)

Configure mongrel and start an instance of ourselves.

    # File lib/shadow.rb, line 53
53:   def serve(me, name, address, port)
54:     fork do
55:       Mongrel::Configurator.new :host => address, :pid_file => "/tmp/shadow.#{name}.pid" do
56:         listener :port => port do
57:           puts "** Serving at #{address}:#{port}/#{name}/ (pid #{Process.pid})"
58:           uri "/#{name}/", :handler => me
59:           setup_signals or run and write_pid_file and join
60:         end
61:       end
62:     end
63:   end