Module: Innate::SingletonMethods

Included in:
Innate
Defined in:
lib/innate.rb,
lib/innate/node.rb,
lib/innate/route.rb,
lib/innate/state.rb,
lib/innate/dynamap.rb

Overview

script_name, path_info = env, env answer = app.call(env) env.merge!(‘SCRIPT_NAME’ => script_name, ‘PATH_INFO’ => path_info) answer

Constant Summary collapse

PROXY_OPTIONS =
{ :port => 'adapter.port', :host => 'adapter.host',
:adapter => 'adapter.handler' }

Instance Method Summary collapse

Instance Method Details

#at(location) ⇒ Object

Answer with object at location.

Examples:


class Hello
  include Innate::Node
  map '/'
end

Innate.at('/') # => Hello


73
74
75
# File 'lib/innate/dynamap.rb', line 73

def at(location)
  DynaMap.at(location)
end

#call(env, mode = ) ⇒ Array

Treat Innate like a rack application, pass the rack env and optionally the mode the application runs in.

Parameters:

  • env (Hash)

    rack env

  • mode (Symbol) (defaults to: )

    indicates the mode of the application

Returns:

  • (Array)

    with [body, header, status]

Author:

  • manveru



166
167
168
# File 'lib/innate.rb', line 166

def call(env, mode = options[:mode])
  middleware(mode).call(env)
end

#defer(&block) ⇒ Object



23
24
25
# File 'lib/innate/state.rb', line 23

def defer(&block)
  STATE.defer(&block)
end

#go_figure_root(backtrace, options) ⇒ Object

Either setting will surpress the warning that might show up on startup and tells you it couldn’t find an explicit root.

In case these options are not passed we will try to figure out a file named ‘start.rb` in the process’ working directory and assume it’s a valid point.

Examples:

Innate can be started by:


Innate.start :file => __FILE__
Innate.start :root => File.dirname(__FILE__)


192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/innate.rb', line 192

def go_figure_root(backtrace, options)
  if root = options[:root]
    root
  elsif file = options[:file]
    File.dirname(file)
  elsif File.file?('start.rb')
    Dir.pwd
  else
    root = File.dirname(backtrace[0][/^(.*?):\d+/, 1])
    Log.warn "No explicit root folder found, assuming it is #{root}"
    root
  end
end

#map(location, object = nil, &block) ⇒ Object

Maps the given object or block to location, object must respond to #call in order to be of any use.

Examples:

with passed object


Innate.map('/', lambda{|env| [200, {}, "Hello, World"] })
Innate.at('/').call({}) # => [200, {}, "Hello, World"]

with passed block


Innate.map('/'){|env| [200, {}, ['Hello, World!']] }
Innate.at('/').call({})


59
60
61
# File 'lib/innate/dynamap.rb', line 59

def map(location, object = nil, &block)
  DynaMap.map(location, object || block)
end

#middleware(mode = , &block) ⇒ Object



170
171
172
# File 'lib/innate.rb', line 170

def middleware(mode = options[:mode], &block)
  options[:middleware_compiler].build(mode, &block)
end

#middleware!(mode = , &block) ⇒ Object



174
175
176
# File 'lib/innate.rb', line 174

def middleware!(mode = options[:mode], &block)
  options[:middleware_compiler].build!(mode, &block)
end

#middleware_recompile(mode = ) ⇒ Object



178
179
180
# File 'lib/innate.rb', line 178

def middleware_recompile(mode = options[:mode])
  options[:middleware_compiler]::COMPILED[mode].compile!
end

#node(location, node = nil) ⇒ Class, Module

Convenience method to include the Node module into node and map to a location.

Parameters:

  • location (#to_s)

    where the node is mapped to

  • node (Node, nil) (defaults to: nil)

    the class that will be a node, will try to look it up if not given

Returns:

  • (Class, Module)

    the node argument or detected class will be returned

See Also:

  • SingletonMethods::node_from_backtrace

Author:

  • manveru



996
997
998
999
1000
1001
# File 'lib/innate/node.rb', line 996

def node(location, node = nil)
  node ||= node_from_backtrace(caller)
  node.__send__(:include, Node)
  node.map(location)
  node
end

#node_from_backtrace(backtrace) ⇒ Class, Module

Cheap hack that works reasonably well to avoid passing self all the time to Innate::node We simply search the file that Innate::node was called in for the first class definition above the line that Innate::node was called and look up the constant. If there are any problems with this (filenames containing ‘:’ or metaprogramming) just pass the node parameter explicitly to Innate::node

Parameters:

  • backtrace (Array<String>, #[])

Returns:

  • (Class, Module)

See Also:

  • SingletonMethods::node

Author:

  • manveru



1018
1019
1020
1021
1022
1023
# File 'lib/innate/node.rb', line 1018

def node_from_backtrace(backtrace)
  filename, lineno = backtrace[0].split(':', 2)
  regexp = /^\s*class\s+(\S+)/
  File.readlines(filename)[0..lineno.to_i].reverse.find{|l| l =~ regexp }
  const_get($1)
end

#Rewrite(key, value = nil, &block) ⇒ Object



106
107
108
# File 'lib/innate/route.rb', line 106

def Rewrite(key, value = nil, &block)
  Rewrite[key] = value || block
end

#Route(key, value = nil, &block) ⇒ Object



102
103
104
# File 'lib/innate/route.rb', line 102

def Route(key, value = nil, &block)
  Route[key] = value || block
end

#setup_dependenciesObject



150
151
152
# File 'lib/innate.rb', line 150

def setup_dependencies
  options[:setup].each{|obj| obj.setup if obj.respond_to?(:setup) }
end

#start(given_options = {}, &block) {|MiddlewareCompiler| ... } ⇒ nil

The method that starts the whole business.

Call Innate.start after you defined your application.

Usually, this is a blocking call and will not return until the adapter has finished, which usually happens when you kill the application or hit ^C.

We do return if options.started is true, which indicates that all you wanted to do is setup the environment and update options.

Examples:

usage


# passing options
Innate.start :adapter => :mongrel, :mode => :live

# defining custom middleware
Innate.start do |m|
  m.innate
end

Parameters:

  • block (Proc)

    will be passed to #middleware!

  • param (Hash)

    a customizable set of options

Yields:

Returns:

  • (nil)

    if options.started is true



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/innate.rb', line 112

def start(given_options = {}, &block)
  root = given_options.delete(:root)
  file = given_options.delete(:file)

  found_root = go_figure_root(caller, :root => root, :file => file)
  Innate.options.roots = [found_root] if found_root

  # Convert some top-level option keys to the internal ones that we use.
  PROXY_OPTIONS.each{|k,v| given_options[v] = given_options.delete(k) }
  given_options.delete_if{|k,v| v.nil? }

  # Merge the user's given options into our existing set, which contains defaults.
  options.merge!(given_options)

  setup_dependencies
  middleware!(options.mode, &block) if block_given?

  return if options.started
  options.started = true

  signal = options.trap
  trap(signal){ stop(10) } if signal

  start!
end

#start!(mode = ) ⇒ Object



138
139
140
# File 'lib/innate.rb', line 138

def start!(mode = options[:mode])
  Adapter.start(middleware(mode))
end

#stop(wait = 3) ⇒ Object



142
143
144
145
146
147
148
# File 'lib/innate.rb', line 142

def stop(wait = 3)
  Log.info("Shutdown within #{wait} seconds")
  Timeout.timeout(wait){ teardown_dependencies }
  Timeout.timeout(wait){ exit }
ensure
  exit!
end

#sync(&block) ⇒ Object

Use this method to achieve thread-safety for sensitive operations.

This should be of most use when manipulating files to prevent other threads from doing the same, no other code will be scheduled during execution of this method.

Parameters:

  • block (Proc)

    the things you want to execute

See Also:



19
20
21
# File 'lib/innate/state.rb', line 19

def sync(&block)
  STATE.sync(&block)
end

#teardown_dependenciesObject



154
155
156
# File 'lib/innate.rb', line 154

def teardown_dependencies
  options[:setup].each{|obj| obj.teardown if obj.respond_to?(:teardown) }
end

#to(object) ⇒ Object

Returns one of the paths the given object is mapped to.

Examples:


class Hello
  include Innate::Node
  map '/'
end

Innate.to(Hello) # => '/'


87
88
89
# File 'lib/innate/dynamap.rb', line 87

def to(object)
  DynaMap.to(object)
end