script_name, path_info = env, env answer = app.call(env) env.merge!(‘SCRIPT_NAME’ => script_name, ‘PATH_INFO’ => path_info) answer
Contains all the module functions for Innate, we keep them in a module so Ramaze can simply use them as well.
Returns an instance of `Rack::Builder` that can be used to start a Innate application.
@return [Rack::Builder]
# File lib/innate/route.rb, line 110 def Rewrite(key, value = nil, &block) Rewrite[key] = value || block end
# File lib/innate/route.rb, line 106 def Route(key, value = nil, &block) Route[key] = value || block end
Answer with object at location.
@example
class Hello include Innate::Node map '/' end Innate.at('/') # => Hello
# File lib/innate/dynamap.rb, line 78 def at(location) DynaMap.at(location) end
Treat Innate like a rack application, pass the rack env and optionally the mode the application runs in.
@param [Hash] env rack env @param [Symbol] mode indicates the mode of the application @default mode options.mode @return [Array] with [body, header, status] @author manveru
# File lib/innate.rb, line 185 def call(env) Innate.app.call(env) end
Returns an instance of `Rack::Cascade` for running Innate applications. This method should be called using `Rack::Builder#run`:
Innate.middleware(:dev) do run Innate.core end
@return [Rack::Cascade]
# File lib/innate.rb, line 212 def core roots, publics = options[:roots], options[:publics] joined = roots.map { |root| publics.map { |p| File.join(root, p) } } joined = joined.flatten.map { |p| Rack::File.new(p) } current = Current.new(Route.new(DynaMap), Rewrite.new(DynaMap)) return Rack::Cascade.new(joined << current, [404, 405]) end
# 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
@example Innate can be started by:
Innate.start :file => __FILE__ Innate.start :root => File.dirname(__FILE__)
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.
# File lib/innate.rb, line 254 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
Maps the given object or block to location, object must respond to call in order to be of any use.
@example with passed object
Innate.map('/', lambda{|env| [200, {}, "Hello, World"] }) Innate.at('/').call({}) # => [200, {}, "Hello, World"]
@example with passed block
Innate.map('/'){|env| [200, {}, ['Hello, World!']] } Innate.at('/').call({})
# File lib/innate/dynamap.rb, line 64 def map(location, object = nil, &block) DynaMap.map(location, object || block) end
Sets the middleware for the given mode.
@example
Innate.middleware(:dev) do use Rack::Head use Rack::Reloader run Innate.core end
@param [to_sym] mode The mode that the middleware belong to. @param [Proc] block Block containing the middleware. This block will be
passed to an instance of `Rack::Builder` and can thus contain everything this class allows you to use.
# File lib/innate.rb, line 238 def middleware(mode, &block) MIDDLEWARE[mode.to_sym] = block recompile_middleware(mode) end
Convenience method to include the Node module into node and map to a location.
@param [to_s] location where the node is mapped to @param [Node, nil] node the class that will be a node, will try to
look it up if not given
@return [Class, Module] the node argument or detected class will be
returned
@api external @see SingletonMethods::node_from_backtrace @author manveru
# File lib/innate/node.rb, line 1076 def node(location, node = nil) node ||= node_from_backtrace(caller) node.__send__(:include, Node) node.map(location) node end
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
@param [Array<String>, #[]] backtrace
@return [Class, Module]
@api internal @see SingletonMethods::node @author manveru
# File lib/innate/node.rb, line 1098 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
Updates `Innate.app` based on the current mode.
@param [to_sym] mode The mode to use.
# File lib/innate.rb, line 194 def recompile_middleware(mode = options[:mode]) mode = mode.to_sym if MIDDLEWARE[mode] and options[:mode] == mode Innate.app = Rack::Builder.new(&MIDDLEWARE[mode]).to_app end end
# File lib/innate.rb, line 173 def setup options.mode ||= (ENV['RACK_ENV'] || :dev) end
# File lib/innate.rb, line 165 def setup_dependencies options[:setup].each{|obj| obj.setup if obj.respond_to?(:setup) } end
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.
@example usage
# passing options Innate.start :adapter => :mongrel, :mode => :live
@return [nil] if options.started is true
@option param :host [String] (‘0.0.0.0’)
IP address or hostname that we respond to - 0.0.0.0 for all
@option param :port [Fixnum] (7000)
Port for the server
@option param :started [boolean] (false)
Indicate that calls Innate::start will be ignored
@option param :adapter [Symbol] (:webrick)
Web server to run on
@option param :setup [Array] ([Innate::Cache, Innate::Node])
Will send ::setup to each element during Innate::start
@option param :header [Hash] ({‘Content-Type’ => ‘text/html’})
Headers that will be merged into the response before Node::call
@option param :trap [String] (‘SIGINT’)
Trap this signal to issue shutdown, nil/false to disable trap
@option param :mode [Symbol] (:dev)
Indicates which default middleware to use, (:dev|:live)
# File lib/innate.rb, line 113 def start(options = {}) 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 return if innate_options.started innate_options.started = true signal = innate_options.trap trap(signal){ stop(10) } if signal mode = self.options[:mode].to_sym # While Rack itself will spit out errors for invalid instances of # Rack::Builder these errors are typically not very user friendly. if !Innate.app or !MIDDLEWARE[mode] raise( ArgumentError, "The mode \"#{mode}\" does not have a set of middleware defined. " "You can define these middleware using " "#{self}.middleware(:#{mode}) { ... }" ) end start! end
# File lib/innate.rb, line 153 def start!(mode = options[:mode]) Adapter.start(Innate.app) end
# File lib/innate.rb, line 157 def stop(wait = 3) Log.info("Shutdown within #{wait} seconds") Timeout.timeout(wait){ teardown_dependencies } Timeout.timeout(wait){ exit } ensure exit! end
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.
@param [Proc] block the things you want to execute
# File lib/innate/state.rb, line 14 def sync(&block) SEMAPHORE.synchronize(&block) end
Generated with the Darkfish Rdoc Generator 2.