dyoder-waves 0.7.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/waves +19 -56
- data/doc/HISTORY +1 -0
- data/doc/LICENSE +22 -0
- data/doc/README +1 -0
- data/doc/VERSION +1 -0
- data/lib/caches/file.rb +48 -0
- data/lib/caches/memcached.rb +40 -0
- data/lib/caches/simple.rb +25 -0
- data/lib/caches/synchronized.rb +25 -0
- data/lib/commands/console.rb +35 -0
- data/lib/commands/generate.rb +52 -0
- data/lib/commands/help.rb +5 -0
- data/lib/commands/{waves-server.rb → server.rb} +16 -3
- data/lib/dispatchers/base.rb +21 -20
- data/lib/dispatchers/default.rb +11 -63
- data/lib/ext/float.rb +13 -0
- data/lib/{utilities → ext}/hash.rb +2 -2
- data/lib/{utilities → ext}/integer.rb +5 -2
- data/lib/ext/kernel.rb +20 -0
- data/lib/ext/module.rb +20 -0
- data/lib/{utilities → ext}/object.rb +3 -5
- data/lib/ext/string.rb +20 -0
- data/lib/ext/symbol.rb +11 -0
- data/lib/ext/tempfile.rb +5 -0
- data/lib/foundations/classic.rb +64 -0
- data/lib/foundations/compact.rb +50 -0
- data/lib/helpers/basic.rb +11 -0
- data/lib/helpers/doc_type.rb +34 -0
- data/lib/helpers/extended.rb +21 -0
- data/lib/helpers/form.rb +3 -1
- data/lib/helpers/formatting.rb +3 -3
- data/lib/helpers/layouts.rb +37 -0
- data/lib/helpers/model.rb +8 -4
- data/lib/helpers/view.rb +2 -4
- data/lib/layers/inflect/english.rb +67 -0
- data/lib/layers/mvc.rb +18 -18
- data/lib/layers/mvc/controllers.rb +41 -0
- data/lib/layers/mvc/extensions.rb +52 -0
- data/lib/layers/orm/{active_record.rb → providers/active_record.rb} +12 -18
- data/lib/layers/orm/{active_record → providers/active_record}/migrations/empty.rb.erb +0 -0
- data/lib/layers/orm/{active_record → providers/active_record}/tasks/generate.rb +1 -1
- data/lib/layers/orm/{active_record → providers/active_record}/tasks/schema.rb +1 -1
- data/lib/layers/orm/{data_mapper.rb → providers/data_mapper.rb} +3 -4
- data/lib/layers/orm/providers/filebase.rb +25 -0
- data/lib/layers/orm/{sequel.rb → providers/sequel.rb} +16 -12
- data/lib/layers/orm/{sequel → providers/sequel}/migrations/empty.rb.erb +0 -0
- data/lib/layers/orm/{sequel → providers/sequel}/tasks/generate.rb +5 -3
- data/lib/layers/orm/{sequel → providers/sequel}/tasks/schema.rb +2 -2
- data/lib/{renderers → layers/renderers}/erubis.rb +10 -13
- data/lib/layers/renderers/haml.rb +47 -0
- data/lib/layers/renderers/markaby.rb +29 -0
- data/lib/matchers/accept.rb +21 -0
- data/lib/matchers/base.rb +30 -0
- data/lib/matchers/content_type.rb +17 -0
- data/lib/matchers/path.rb +67 -0
- data/lib/matchers/query.rb +21 -0
- data/lib/matchers/request.rb +27 -0
- data/lib/matchers/resource.rb +19 -0
- data/lib/matchers/traits.rb +19 -0
- data/lib/matchers/uri.rb +20 -0
- data/lib/renderers/mixin.rb +15 -29
- data/lib/resources/mixin.rb +132 -0
- data/lib/resources/paths.rb +34 -0
- data/lib/runtime/configuration.rb +55 -135
- data/lib/runtime/console.rb +4 -1
- data/lib/runtime/logger.rb +24 -48
- data/lib/runtime/mime_types.rb +516 -2
- data/lib/runtime/mocks.rb +14 -0
- data/lib/runtime/monitor.rb +32 -0
- data/lib/runtime/request.rb +107 -39
- data/lib/runtime/response.rb +5 -2
- data/lib/runtime/response_mixin.rb +43 -22
- data/lib/runtime/runtime.rb +67 -0
- data/lib/runtime/server.rb +14 -101
- data/lib/runtime/session.rb +4 -43
- data/lib/runtime/worker.rb +86 -0
- data/lib/servers/base.rb +42 -0
- data/lib/servers/mongrel.rb +13 -0
- data/lib/servers/webrick.rb +13 -0
- data/lib/tasks/gem.rb +1 -0
- data/lib/tasks/generate.rb +67 -62
- data/lib/views/errors.rb +49 -0
- data/lib/views/mixin.rb +34 -82
- data/lib/waves.rb +36 -55
- data/samples/blog/Rakefile +25 -0
- data/samples/blog/configurations/default.rb +11 -0
- data/samples/blog/configurations/development.rb +29 -0
- data/samples/blog/configurations/production.rb +26 -0
- data/samples/blog/models/comment.rb +23 -0
- data/samples/blog/models/entry.rb +31 -0
- data/samples/blog/public/css/site.css +13 -0
- data/samples/blog/public/javascript/jquery-1.2.6.min.js +32 -0
- data/samples/blog/public/javascript/site.js +13 -0
- data/samples/blog/resources/entry.rb +39 -0
- data/samples/blog/resources/map.rb +9 -0
- data/samples/blog/schema/migrations/001_initial_schema.rb +17 -0
- data/samples/blog/schema/migrations/002_add_comments.rb +18 -0
- data/samples/blog/schema/migrations/templates/empty.rb.erb +9 -0
- data/samples/blog/startup.rb +8 -0
- data/samples/blog/templates/comment/add.mab +12 -0
- data/samples/blog/templates/comment/list.mab +6 -0
- data/samples/blog/templates/entry/edit.mab +14 -0
- data/samples/blog/templates/entry/list.mab +16 -0
- data/samples/blog/templates/entry/show.mab +18 -0
- data/samples/blog/templates/entry/summary.mab +9 -0
- data/samples/blog/templates/errors/not_found_404.mab +7 -0
- data/{app → samples/blog}/templates/errors/server_error_500.mab +0 -0
- data/samples/blog/templates/layouts/default.mab +19 -0
- data/samples/blog/templates/waves/status.mab +85 -0
- data/templates/classic/Rakefile +130 -0
- data/templates/classic/configurations/default.rb.erb +9 -0
- data/{app → templates/classic}/configurations/development.rb.erb +3 -7
- data/{app → templates/classic}/configurations/production.rb.erb +3 -4
- data/templates/classic/resources/map.rb.erb +8 -0
- data/templates/classic/startup.rb.erb +11 -0
- data/{app → templates/classic}/templates/errors/not_found_404.mab +0 -0
- data/templates/classic/templates/errors/server_error_500.mab +2 -0
- data/{app → templates/classic}/templates/layouts/default.mab +0 -0
- data/templates/compact/startup.rb.erb +11 -0
- metadata +967 -144
- data/app/Rakefile +0 -14
- data/app/bin/waves-console +0 -4
- data/app/bin/waves-server +0 -4
- data/app/configurations/mapping.rb.erb +0 -13
- data/app/controllers/.gitignore +0 -0
- data/app/doc/.gitignore +0 -0
- data/app/helpers/.gitignore +0 -0
- data/app/lib/application.rb.erb +0 -5
- data/app/lib/tasks/.gitignore +0 -0
- data/app/log/.gitignore +0 -0
- data/app/models/.gitignore +0 -0
- data/app/public/css/.gitignore +0 -0
- data/app/public/flash/.gitignore +0 -0
- data/app/public/images/.gitignore +0 -0
- data/app/public/javascript/.gitignore +0 -0
- data/app/schema/migrations/.gitignore +0 -0
- data/app/startup.rb +0 -5
- data/app/tmp/sessions/.gitignore +0 -0
- data/app/views/.gitignore +0 -0
- data/bin/waves-console +0 -4
- data/bin/waves-server +0 -4
- data/lib/commands/waves-console.rb +0 -21
- data/lib/controllers/base.rb +0 -11
- data/lib/controllers/mixin.rb +0 -165
- data/lib/foundations/default.rb +0 -26
- data/lib/foundations/simple.rb +0 -30
- data/lib/helpers/asset_helper.rb +0 -67
- data/lib/helpers/common.rb +0 -66
- data/lib/helpers/default.rb +0 -13
- data/lib/helpers/number_helper.rb +0 -25
- data/lib/helpers/tag_helper.rb +0 -58
- data/lib/helpers/url_helper.rb +0 -77
- data/lib/layers/default_errors.rb +0 -26
- data/lib/layers/orm/filebase.rb +0 -22
- data/lib/layers/simple.rb +0 -35
- data/lib/layers/simple_errors.rb +0 -23
- data/lib/mapping/mapping.rb +0 -289
- data/lib/mapping/pretty_urls.rb +0 -96
- data/lib/renderers/markaby.rb +0 -33
- data/lib/runtime/application.rb +0 -69
- data/lib/runtime/blackboard.rb +0 -57
- data/lib/runtime/debugger.rb +0 -9
- data/lib/runtime/response_proxy.rb +0 -30
- data/lib/tasks/cluster.rb +0 -26
- data/lib/utilities/inflect.rb +0 -110
- data/lib/utilities/inflect/english.rb +0 -84
- data/lib/utilities/module.rb +0 -21
- data/lib/utilities/proc.rb +0 -16
- data/lib/utilities/string.rb +0 -61
- data/lib/utilities/symbol.rb +0 -10
- data/lib/views/base.rb +0 -9
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Waves
|
|
2
|
+
module Mocks
|
|
3
|
+
|
|
4
|
+
def dispatcher ; Waves::Dispatchers::Default ; end
|
|
5
|
+
def request ; Rack::MockRequest.new( dispatcher.new ) ; end
|
|
6
|
+
def env( uri, opts ) ; Rack::MockRequest.env_for( uri, opts ) ; end
|
|
7
|
+
def get( uri, opts = {} ) ; request.get( uri, opts ) ; end
|
|
8
|
+
def put( uri, opts = {} ) ; request.put( uri, opts ) ; end
|
|
9
|
+
def post( uri, opts = {} ) ; request.post( uri, opts ) ; end
|
|
10
|
+
def delete( uri, opts = {} ) ; request.delete( uri, opts ) ; end
|
|
11
|
+
def head( uri, opts = {} ) ; request.request( 'HEAD', uri, opts ) ; end
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Waves
|
|
2
|
+
|
|
3
|
+
class Monitor
|
|
4
|
+
|
|
5
|
+
def initialize( options ) ; @options = options ; end
|
|
6
|
+
|
|
7
|
+
def start( manager )
|
|
8
|
+
@manager = manager
|
|
9
|
+
@pid = fork do
|
|
10
|
+
safe_trap('INT','TERM') do
|
|
11
|
+
Waves::Logger.info "Monitor stopped ..."
|
|
12
|
+
exit
|
|
13
|
+
end
|
|
14
|
+
loop { fix unless check ; sleep interval }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def fix
|
|
19
|
+
@manager.restart
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# you need to implement this
|
|
23
|
+
def check ; true ; end
|
|
24
|
+
|
|
25
|
+
# defaults to every 60 seconds
|
|
26
|
+
def interval ; @options[ :interval ] ; end
|
|
27
|
+
|
|
28
|
+
def stop ; Process.kill( 'INT', @pid ) ; end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
data/lib/runtime/request.rb
CHANGED
|
@@ -1,78 +1,146 @@
|
|
|
1
1
|
module Waves
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
# Waves::Request represents an HTTP request and provides convenient methods for accessing request attributes.
|
|
4
|
+
# See Rack::Request for documentation of any method not defined here.
|
|
5
|
+
|
|
3
6
|
class Request
|
|
4
7
|
|
|
5
8
|
class ParseError < Exception ; end
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
class Query ; include Attributes ; end
|
|
11
|
+
|
|
12
|
+
attr_reader :response, :session, :traits
|
|
8
13
|
|
|
9
14
|
# Create a new request. Takes a env parameter representing the request passed in from Rack.
|
|
10
15
|
# You shouldn't need to call this directly.
|
|
11
16
|
def initialize( env )
|
|
12
|
-
@
|
|
17
|
+
@traits = Class.new { include Attributes }.new( :waves => {} )
|
|
18
|
+
@request = Rack::Request.new( env ).freeze
|
|
13
19
|
@response = Waves::Response.new( self )
|
|
14
20
|
@session = Waves::Session.new( self )
|
|
15
|
-
@blackboard = Waves::Blackboard.new( self )
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
def rack_request; @request; end
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@request.send(name,*args)
|
|
24
|
+
|
|
25
|
+
# Methods delegated directly to rack
|
|
26
|
+
%w( url scheme host port body query_string content_type media_type content_length referer ).each do |m|
|
|
27
|
+
define_method( m ) { @request.send( m ) }
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
# The request path (PATH_INFO). Ex: +/entry/2008-01-17+
|
|
27
|
-
def path
|
|
28
|
-
@request.path_info
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# The request domain. Ex: +www.fubar.com+
|
|
32
|
-
def domain
|
|
33
|
-
@request.host
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# The request content type.
|
|
37
|
-
def content_type
|
|
38
|
-
@request.env['CONTENT_TYPE']
|
|
39
|
-
end
|
|
31
|
+
def path ; @request.path_info ; end
|
|
40
32
|
|
|
41
|
-
#
|
|
42
|
-
|
|
33
|
+
# Access to "params" - aka the query string - as a hash
|
|
34
|
+
def query ; @request.params ; end
|
|
35
|
+
|
|
36
|
+
alias_method :params, :query
|
|
37
|
+
alias_method :domain, :host
|
|
43
38
|
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
39
|
+
# Request method predicates, defined in terms of #method.
|
|
40
|
+
%w{get post put delete head options trace}.
|
|
41
|
+
each { |m| define_method( m ) { method.to_s == m } }
|
|
48
42
|
|
|
49
43
|
# The request method. Because browsers can't send PUT or DELETE
|
|
50
44
|
# requests this can be simulated by sending a POST with a hidden
|
|
51
45
|
# field named '_method' and a value with 'PUT' or 'DELETE'. Also
|
|
52
46
|
# accepted is when a query parameter named '_method' is provided.
|
|
53
47
|
def method
|
|
54
|
-
@method ||=
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
@method ||= ( ( ( m = @request.request_method.downcase ) == 'post' and
|
|
49
|
+
( n = @request['_method'] ) ) ? n.downcase : m ).intern
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def []( key ) ; @request.env[ key.to_s.upcase ] ; end
|
|
53
|
+
|
|
54
|
+
# access HTTP headers as methods
|
|
55
|
+
def method_missing( name, *args, &body )
|
|
56
|
+
return super unless args.empty? and body.nil?
|
|
57
|
+
key = "HTTP_#{name.to_s.upcase}"
|
|
58
|
+
@request.env[ key ] if @request.env.has_key?( key )
|
|
64
59
|
end
|
|
65
60
|
|
|
66
61
|
# Raise a not found exception.
|
|
67
62
|
def not_found
|
|
68
|
-
raise Waves::Dispatchers::NotFoundError
|
|
63
|
+
raise Waves::Dispatchers::NotFoundError, "#{@request.url} not found."
|
|
69
64
|
end
|
|
70
65
|
|
|
71
66
|
# Issue a redirect for the given path.
|
|
72
67
|
def redirect( path, status = '302' )
|
|
73
68
|
raise Waves::Dispatchers::Redirect.new( path, status )
|
|
74
69
|
end
|
|
70
|
+
|
|
71
|
+
class Accept < Array
|
|
72
|
+
|
|
73
|
+
def =~(arg) ; self.include? arg ; end
|
|
74
|
+
def ===(arg) ; self.include? arg ; end
|
|
75
|
+
|
|
76
|
+
def include?(arg)
|
|
77
|
+
return arg.any? { |pat| self.include?( pat ) } if arg.is_a? Array
|
|
78
|
+
arg = arg.to_s.split('/')
|
|
79
|
+
self.any? do |entry|
|
|
80
|
+
false if entry == '*/*' or entry == '*'
|
|
81
|
+
entry = entry.split('/')
|
|
82
|
+
if arg.size == 1 # implicit wildcard in arg
|
|
83
|
+
arg[0] == entry[0] or arg[0] == entry[1]
|
|
84
|
+
else
|
|
85
|
+
arg == entry
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.parse(string)
|
|
91
|
+
string.split(',').inject(self.new) { |a, entry| a << entry.split( ';' ).first.strip; a }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def default
|
|
95
|
+
return 'text/html' if self.include?('text/html')
|
|
96
|
+
find { |entry| ! entry.match(/\*/) } || 'text/html'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# this is a hack - need to incorporate browser variations for "accept" here ...
|
|
102
|
+
# def accept ; Accept.parse(@request.env['HTTP_ACCEPT']).unshift( Waves.config.mime_types[ path ] ).compact.uniq ; end
|
|
103
|
+
def accept ; @accept ||= Accept.parse( Waves.config.mime_types[ path.downcase ] || 'text/html' ) ; end
|
|
104
|
+
def accept_charset ; @charset ||= Accept.parse(@request.env['HTTP_ACCEPT_CHARSET']) ; end
|
|
105
|
+
def accept_language ; @lang ||= Accept.parse(@request.env['HTTP_ACCEPT_LANGUAGE']) ; end
|
|
106
|
+
|
|
107
|
+
module Utilities
|
|
108
|
+
|
|
109
|
+
def self.destructure( hash )
|
|
110
|
+
destructured = {}
|
|
111
|
+
hash.keys.map { |key| key.split('.') }.each do |keys|
|
|
112
|
+
destructure_with_array_keys(hash, '', keys, destructured)
|
|
113
|
+
end
|
|
114
|
+
destructured
|
|
115
|
+
end
|
|
75
116
|
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def self.destructure_with_array_keys( hash, prefix, keys, destructured )
|
|
120
|
+
if keys.length == 1
|
|
121
|
+
key = "#{prefix}#{keys.first}"
|
|
122
|
+
val = hash[key]
|
|
123
|
+
destructured[keys.first.intern] = case val
|
|
124
|
+
when String
|
|
125
|
+
val.strip
|
|
126
|
+
when Hash, Array
|
|
127
|
+
val
|
|
128
|
+
when Array
|
|
129
|
+
val
|
|
130
|
+
when nil
|
|
131
|
+
raise key.inspect
|
|
132
|
+
end
|
|
133
|
+
else
|
|
134
|
+
destructured = ( destructured[keys.first.intern] ||= {} )
|
|
135
|
+
new_prefix = "#{prefix}#{keys.shift}."
|
|
136
|
+
destructure_with_array_keys( hash, new_prefix, keys, destructured )
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
|
|
76
142
|
end
|
|
77
143
|
|
|
78
144
|
end
|
|
145
|
+
|
|
146
|
+
|
data/lib/runtime/response.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
module Waves
|
|
2
|
+
|
|
2
3
|
# Waves::Response represents an HTTP response and has methods for constructing a response.
|
|
3
4
|
# These include setters for +content_type+, +content_length+, +location+, and +expires+
|
|
4
|
-
# headers. You may also set the headers directly using the [] operator.
|
|
5
|
+
# headers. You may also set the headers directly using the [] operator.
|
|
6
|
+
# See Rack::Response for documentation of any method not defined here.
|
|
7
|
+
|
|
5
8
|
class Response
|
|
6
9
|
|
|
7
10
|
attr_reader :request
|
|
@@ -28,7 +31,7 @@ module Waves
|
|
|
28
31
|
# attempt to further modify the response once this method is called. You don't usually
|
|
29
32
|
# need to call it yourself, since it is called by the dispatcher once request processing
|
|
30
33
|
# is finished.
|
|
31
|
-
def finish ;
|
|
34
|
+
def finish ; @response.finish ; end
|
|
32
35
|
|
|
33
36
|
# Methods not explicitly defined by Waves::Response are delegated to Rack::Response.
|
|
34
37
|
# Check the Rack documentation for more informations
|
|
@@ -3,36 +3,57 @@ module Waves
|
|
|
3
3
|
# Defines a set of methods that simplify accessing common request and response methods.
|
|
4
4
|
# These include methods not necessarily associated with the Waves::Request and Waves::Response
|
|
5
5
|
# objects, but which may still be useful for constructing a response.
|
|
6
|
-
#
|
|
7
6
|
# This mixin assumes that a @request@ accessor already exists.
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
module ResponseMixin
|
|
9
|
+
|
|
9
10
|
# Access the response.
|
|
10
11
|
def response; request.response; end
|
|
11
|
-
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
#
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
|
|
13
|
+
def resource ; traits.waves.resource ; end
|
|
14
|
+
|
|
15
|
+
def traits ; request.traits ; end
|
|
16
|
+
|
|
17
|
+
# Access to the query string as a object where the keys are accessors
|
|
18
|
+
# You can still access the original query as request.query
|
|
19
|
+
def query ; @query ||= Waves::Request::Query.new( request.query ) ; end
|
|
20
|
+
|
|
21
|
+
# Elements captured the path
|
|
22
|
+
def captured ; @captured ||= traits.waves.captured ; end
|
|
23
|
+
|
|
24
|
+
# Both the query and capture merged together
|
|
25
|
+
def params
|
|
26
|
+
query = captured ? request.query.merge( captured.to_h ) : request.query
|
|
27
|
+
@params ||= Waves::Request::Query.new( query )
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
%w( session path url domain not_found ).each do | m |
|
|
31
|
+
define_method( m ) { request.send( m ) }
|
|
32
|
+
end
|
|
33
|
+
|
|
21
34
|
# Issue a redirect for the given location.
|
|
22
35
|
def redirect(location, status = '302'); request.redirect(location, status); end
|
|
23
|
-
# Access the primary application's models
|
|
24
|
-
def models; Waves.application.models; end
|
|
25
|
-
# Access the primary application's views
|
|
26
|
-
def views; Waves.application.views; end
|
|
27
|
-
# Access the primary application's controllers
|
|
28
|
-
def controllers; Waves.application.controllers; end
|
|
29
|
-
# Raise a "not found" exception.
|
|
30
|
-
def not_found; request.not_found; end
|
|
31
36
|
# Access the Waves::Logger.
|
|
32
37
|
def log; Waves::Logger; end
|
|
33
|
-
#
|
|
34
|
-
def
|
|
38
|
+
# access stuff from an app
|
|
39
|
+
def app_name ; self.class.rootname.snake_case.to_sym ; end
|
|
40
|
+
def app ; eval( "::#{app_name.to_s.camel_case}" ) ; end
|
|
41
|
+
def paths( rname = nil )
|
|
42
|
+
( rname.nil? ? resource.class.paths : app::Resources[ rname ].paths ).new( request )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def basename ; @basename ||= path.sub(/\.([^\.]+)$/,'') ; end
|
|
35
46
|
|
|
47
|
+
def extension
|
|
48
|
+
@extension ||= if ( m = path.match(/\.([^\.]+)$/) )
|
|
49
|
+
m[1]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def render( path, assigns = {} )
|
|
54
|
+
Waves::Views::Base.new( request ).render( path, assigns )
|
|
55
|
+
end
|
|
56
|
+
|
|
36
57
|
end
|
|
37
58
|
|
|
38
59
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Waves
|
|
2
|
+
|
|
3
|
+
# A temporary measure until the applications "array" becomes a hash.
|
|
4
|
+
# Currently used to keep track of all loaded Waves applications.
|
|
5
|
+
class Applications < Array
|
|
6
|
+
def []( name ) ; self.find { |app| app == name.to_s.camel_case } ; end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.config; instance.config ; end
|
|
10
|
+
|
|
11
|
+
# The list of all loaded applications
|
|
12
|
+
def self.applications ; @applications ||= Applications.new ; end
|
|
13
|
+
|
|
14
|
+
# Access the principal Waves application.
|
|
15
|
+
def self.main ; applications.first ; end
|
|
16
|
+
|
|
17
|
+
# Register a module as a Waves application.
|
|
18
|
+
def self.<< ( app )
|
|
19
|
+
applications << app if Module === app
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns the most recently created instance of Waves::Runtime.
|
|
23
|
+
def self.instance ; Waves::Runtime.instance ; end
|
|
24
|
+
|
|
25
|
+
def self.version ; File.read( File.expand_path( "#{File.dirname(__FILE__)}/../../doc/VERSION" ) ) ; end
|
|
26
|
+
def self.license ; File.read( File.expand_path( "#{File.dirname(__FILE__)}/../../doc/LICENSE" ) ) ; end
|
|
27
|
+
|
|
28
|
+
def self.method_missing(name,*args,&block) ; instance.send(name,*args,&block) ; end
|
|
29
|
+
|
|
30
|
+
# A Waves::Runtime takes an inert application module and gives it concrete, pokeable form.
|
|
31
|
+
# Waves::Server and Waves::Console are types of runtime.
|
|
32
|
+
class Runtime
|
|
33
|
+
|
|
34
|
+
class << self; attr_accessor :instance; end
|
|
35
|
+
|
|
36
|
+
# Accessor for options passed to the runtime.
|
|
37
|
+
attr_reader :options
|
|
38
|
+
|
|
39
|
+
# Create a new Waves application instance.
|
|
40
|
+
def initialize( options={} )
|
|
41
|
+
@options = options
|
|
42
|
+
Dir.chdir options[:directory] if options[:directory]
|
|
43
|
+
Runtime.instance = self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The 'mode' of the runtime determines which configuration it will run under.
|
|
47
|
+
def mode ; options[:mode]||:development ; end
|
|
48
|
+
|
|
49
|
+
# Returns true if debug was set to true in the current configuration.
|
|
50
|
+
def debug? ; options[:debugger] or config.debug ; end
|
|
51
|
+
|
|
52
|
+
# Returns the current configuration.
|
|
53
|
+
def config ; Waves.main::Configurations[ mode ] ; end
|
|
54
|
+
|
|
55
|
+
# Reload the modules specified in the current configuration.
|
|
56
|
+
def reload ; config.reloadable.each { |mod| mod.reload } ; end
|
|
57
|
+
|
|
58
|
+
# Start and / or access the Waves::Logger instance.
|
|
59
|
+
def log ; @log ||= Waves::Logger.start ; end
|
|
60
|
+
|
|
61
|
+
# Provides access to the server mutex for thread-safe operation.
|
|
62
|
+
def synchronize( &block ) ; ( @mutex ||= Mutex.new ).synchronize( &block ) ; end
|
|
63
|
+
def synchronize? ; !options[ :turbo ] ; end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
data/lib/runtime/server.rb
CHANGED
|
@@ -1,107 +1,20 @@
|
|
|
1
1
|
module Waves
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# ports [ 2020, 2021, 2022 ]
|
|
9
|
-
#
|
|
10
|
-
# Then you could start up instances on all three ports using:
|
|
11
|
-
#
|
|
12
|
-
# rake cluster:start mode=development
|
|
13
|
-
#
|
|
14
|
-
# This is the equivalent of running:
|
|
15
|
-
#
|
|
16
|
-
# waves-server -c development -p 2020 -d
|
|
17
|
-
# waves-server -c development -p 2021 -d
|
|
18
|
-
# waves-server -c development -p 2022 -d
|
|
19
|
-
#
|
|
20
|
-
# The +cluster:stop+ task stops all of the instances.
|
|
21
|
-
#
|
|
22
|
-
class Server < Application
|
|
23
|
-
|
|
24
|
-
# Access the server thread.
|
|
25
|
-
attr_reader :thread
|
|
26
|
-
|
|
27
|
-
# Access the host we're binding to (set via the configuration).
|
|
28
|
-
def host ; options[:host] || config.host ; end
|
|
29
|
-
|
|
30
|
-
# Access the port we're listening on (set via the configuration).
|
|
31
|
-
def port ; options[:port] || config.port ; end
|
|
32
|
-
|
|
33
|
-
# Run the server as a daemon. Corresponds to the -d switch on +waves-server+.
|
|
34
|
-
def daemonize
|
|
35
|
-
pwd = Dir.pwd
|
|
36
|
-
Daemonize.daemonize( Waves::Logger.output )
|
|
37
|
-
Dir.chdir(pwd)
|
|
38
|
-
File.write( :log / "#{port}.pid", $$ )
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def trap(signal)
|
|
42
|
-
Kernel::trap(signal) { yield }
|
|
43
|
-
Thread.new { loop {sleep 1} } if RUBY_PLATFORM =~ /mswin32/
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Start and / or access the Waves::Logger instance.
|
|
47
|
-
def log
|
|
48
|
-
@log ||= Waves::Logger.start
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Start the server.
|
|
52
|
-
def start
|
|
53
|
-
daemonize if options[:daemon]
|
|
54
|
-
start_debugger if options[:debugger]
|
|
55
|
-
log.info "** Waves Server starting on #{host}:#{port}"
|
|
56
|
-
handler, options = config.handler
|
|
57
|
-
handler.run( config.application.to_app, options ) do |server|
|
|
58
|
-
@server = server
|
|
59
|
-
self.trap('INT') { puts; stop } if @server.respond_to? :stop
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Stop the server.
|
|
64
|
-
def stop
|
|
65
|
-
log.info "** Waves Server Stopping ..."
|
|
66
|
-
if options[:daemon]
|
|
67
|
-
pid_file = :log / $$ + '.pid'; FileUtils.rm( pid_file ) if File.exist?( pid_file )
|
|
68
|
-
end
|
|
69
|
-
@server.stop
|
|
70
|
-
log.info "** Waves Server Stopped"
|
|
2
|
+
|
|
3
|
+
class Server < Worker
|
|
4
|
+
|
|
5
|
+
def start_tasks
|
|
6
|
+
@server = config.server.new( application, host, port )
|
|
7
|
+
@server.start
|
|
71
8
|
end
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class << self
|
|
77
|
-
private :new, :dup, :clone
|
|
78
|
-
# Start or restart the server.
|
|
79
|
-
def run( options={} )
|
|
80
|
-
@server.stop if @server; @server = new( options ); @server.start
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Allows us to access the Waves::Server instance.
|
|
84
|
-
def method_missing(*args)
|
|
85
|
-
@server.send(*args)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
#-- Probably wouldn't need this if I added a block parameter to method_missing.
|
|
89
|
-
def synchronize(&block) ; @server.synchronize(&block) ; end
|
|
90
|
-
end
|
|
91
|
-
|
|
9
|
+
|
|
10
|
+
def stop_tasks ; @server.stop ; end
|
|
11
|
+
|
|
92
12
|
private
|
|
93
13
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
|
|
99
|
-
log.info "Debugger enabled"
|
|
100
|
-
rescue Exception
|
|
101
|
-
log.info "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'"
|
|
102
|
-
exit
|
|
103
|
-
end
|
|
104
|
-
end
|
|
14
|
+
def application ; @app ||= config.application.to_app ; end
|
|
15
|
+
def port ; @port ||= options[:port] or config.port ; end
|
|
16
|
+
def host ; @host ||= options[:host] or config.host ; end
|
|
17
|
+
|
|
105
18
|
end
|
|
106
19
|
|
|
107
|
-
end
|
|
20
|
+
end
|