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


78
79
80
# File 'lib/innate/dynamap.rb', line 78

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



160
161
162
# File 'lib/innate.rb', line 160

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

#deferObject



18
19
20
21
22
23
24
25
# File 'lib/innate/state.rb', line 18

def defer
  outer = ::Thread.current
  ::Thread.new{
    inner = ::Thread.current
    outer.keys.each{|k| inner[k] = outer[k] }
    yield
  }
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__)


186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/innate.rb', line 186

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({})


64
65
66
# File 'lib/innate/dynamap.rb', line 64

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

#middleware(mode = , &block) ⇒ Object



164
165
166
# File 'lib/innate.rb', line 164

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

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



168
169
170
# File 'lib/innate.rb', line 168

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

#middleware_recompile(mode = ) ⇒ Object



172
173
174
# File 'lib/innate.rb', line 172

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



1028
1029
1030
1031
1032
1033
# File 'lib/innate/node.rb', line 1028

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



1050
1051
1052
1053
1054
1055
# File 'lib/innate/node.rb', line 1050

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{|ln| ln =~ regexp }
  const_get($1)
end

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



110
111
112
# File 'lib/innate/route.rb', line 110

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

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



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

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

#setup_dependenciesObject



144
145
146
# File 'lib/innate.rb', line 144

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

#start(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



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/innate.rb', line 106

def start(options = {}, &block)
  root, file = options.delete(:root), options.delete(:file)
  innate_options = Innate.options

  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{|given, proxy| options[proxy] = options[given] }
  options.delete_if{|key, value| PROXY_OPTIONS[key] || value.nil? }

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

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

  return if innate_options.started
  innate_options.started = true

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

  start!
end

#start!(mode = ) ⇒ Object



132
133
134
# File 'lib/innate.rb', line 132

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

#stop(wait = 3) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/innate.rb', line 136

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



14
15
16
# File 'lib/innate/state.rb', line 14

def sync(&block)
  SEMAPHORE.synchronize(&block)
end

#teardown_dependenciesObject



148
149
150
# File 'lib/innate.rb', line 148

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) # => '/'


92
93
94
# File 'lib/innate/dynamap.rb', line 92

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