strelka 0.0.1.pre.187 → 0.0.1.pre.193

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.
Files changed (47) hide show
  1. data.tar.gz.sig +0 -0
  2. data/ChangeLog +94 -26
  3. data/Manifest.txt +4 -2
  4. data/examples/apps/ws-echo +17 -0
  5. data/lib/strelka/app.rb +26 -24
  6. data/lib/strelka/app/auth.rb +2 -1
  7. data/lib/strelka/app/errors.rb +1 -1
  8. data/lib/strelka/app/filters.rb +1 -1
  9. data/lib/strelka/app/negotiation.rb +1 -1
  10. data/lib/strelka/app/parameters.rb +2 -2
  11. data/lib/strelka/app/restresources.rb +1 -1
  12. data/lib/strelka/app/routing.rb +3 -2
  13. data/lib/strelka/app/sessions.rb +3 -3
  14. data/lib/strelka/app/templating.rb +3 -3
  15. data/lib/strelka/authprovider.rb +2 -10
  16. data/lib/strelka/behavior/plugin.rb +3 -3
  17. data/lib/strelka/httprequest.rb +5 -2
  18. data/lib/strelka/httprequest/session.rb +3 -2
  19. data/lib/strelka/httpresponse/session.rb +8 -9
  20. data/lib/strelka/mixins.rb +15 -0
  21. data/lib/strelka/plugins.rb +257 -0
  22. data/lib/strelka/router/default.rb +27 -2
  23. data/lib/strelka/session.rb +20 -2
  24. data/lib/strelka/session/db.rb +20 -10
  25. data/lib/strelka/session/default.rb +41 -18
  26. data/spec/lib/helpers.rb +1 -1
  27. data/spec/strelka/app/auth_spec.rb +1 -1
  28. data/spec/strelka/app/errors_spec.rb +1 -1
  29. data/spec/strelka/app/filters_spec.rb +1 -1
  30. data/spec/strelka/app/negotiation_spec.rb +1 -1
  31. data/spec/strelka/app/parameters_spec.rb +1 -1
  32. data/spec/strelka/app/restresources_spec.rb +1 -1
  33. data/spec/strelka/app/routing_spec.rb +4 -1
  34. data/spec/strelka/app/sessions_spec.rb +63 -17
  35. data/spec/strelka/app/templating_spec.rb +1 -1
  36. data/spec/strelka/app_spec.rb +13 -5
  37. data/spec/strelka/httprequest/session_spec.rb +44 -23
  38. data/spec/strelka/httprequest_spec.rb +21 -0
  39. data/spec/strelka/httpresponse/session_spec.rb +143 -0
  40. data/spec/strelka/{app/plugins_spec.rb → plugins_spec.rb} +64 -53
  41. data/spec/strelka/router/default_spec.rb +15 -0
  42. data/spec/strelka/router/exclusive_spec.rb +14 -0
  43. data/spec/strelka/session/db_spec.rb +11 -0
  44. data/spec/strelka/session/default_spec.rb +10 -2
  45. metadata +119 -37
  46. metadata.gz.sig +0 -0
  47. data/lib/strelka/app/plugins.rb +0 -284
@@ -1,284 +0,0 @@
1
- # -*- ruby -*-
2
- # vim: set nosta noet ts=4 sw=4:
3
- # encoding: utf-8
4
-
5
- require 'set'
6
- require 'tsort'
7
-
8
- require 'strelka' unless defined?( Strelka )
9
- require 'strelka/app' unless defined?( Strelka::App )
10
- require 'strelka/mixins'
11
-
12
- class Strelka::App
13
- extend Strelka::MethodUtilities
14
-
15
- # A topologically-sorted hash for plugin management
16
- class PluginRegistry < Hash
17
- include TSort
18
- alias_method :tsort_each_node, :each_key
19
- def tsort_each_child( node, &block )
20
- mod = fetch( node ) { [] }
21
- if mod.respond_to?( :successors )
22
- mod.successors.each( &block )
23
- else
24
- mod.each( &block )
25
- end
26
- end
27
- end
28
-
29
-
30
- ##
31
- # The Hash of loaded plugin modules, keyed by their downcased and symbolified
32
- # name (e.g., Strelka::App::Templating => :templating)
33
- singleton_attr_reader :loaded_plugins
34
- @loaded_plugins = PluginRegistry.new
35
-
36
-
37
- # Plugin Module extension -- adds registration, load-order support, etc.
38
- module Plugin
39
-
40
- ### Mixin hook -- extend including objects instead.
41
- def self::included( mod )
42
- mod.extend( self )
43
- end
44
-
45
-
46
- ### Extension hook -- Extend the given object with methods for setting it
47
- ### up as a plugin for Strelka::Apps.
48
- def self::extended( object )
49
- Strelka.log.debug "Extending %p as a Strelka::App::Plugin" % [ object ]
50
-
51
- super
52
- name = object.plugin_name
53
- object.instance_variable_set( :@successors, Set.new )
54
-
55
- # Register any pending dependencies for the newly-loaded plugin
56
- if (( deps = Strelka::App.loaded_plugins[name] ))
57
- Strelka.log.debug " installing deferred deps for %p" % [ name ]
58
- object.run_after( *deps )
59
- end
60
-
61
- Strelka.log.debug " adding %p (%p) to the plugin registry" % [ name, object ]
62
- Strelka::App.loaded_plugins[ name ] = object
63
- end
64
-
65
-
66
- #############################################################
67
- ### A P P E N D E D M E T H O D S
68
- #############################################################
69
-
70
- # An Array that tracks which plugins should be installed after itself.
71
- attr_reader :successors
72
-
73
-
74
- ### Return the name of the receiving plugin
75
- def plugin_name
76
- name = self.name || "anonymous#{self.object_id}"
77
- name.sub!( /.*::/, '' )
78
- return name.downcase.to_sym
79
- end
80
-
81
-
82
- ### Register the receiver as needing to be run before +other_plugins+ for requests, and
83
- ### *after* them for responses.
84
- def run_before( *other_plugins )
85
- name = self.plugin_name
86
- other_plugins.each do |other_name|
87
- Strelka::App.loaded_plugins[ other_name ] ||= []
88
- mod = Strelka::App.loaded_plugins[ other_name ]
89
-
90
- if mod.respond_to?( :run_after )
91
- mod.run_after( name )
92
- else
93
- Strelka.log.debug "%p plugin not yet loaded; setting up pending deps" % [ other_name ]
94
- mod << name
95
- end
96
- end
97
- end
98
-
99
-
100
- ### Register the receiver as needing to be run after +other_plugins+ for requests, and
101
- ### *before* them for responses.
102
- def run_after( *other_plugins )
103
- Strelka.log.debug " %p will run after %p" % [ self, other_plugins ]
104
- self.successors.merge( other_plugins )
105
- end
106
-
107
- end # module Plugin
108
-
109
-
110
- # Plugin system
111
- module Plugins
112
-
113
- ### Inclusion callback -- add class methods and instance variables without
114
- ### needing a separate call to #extend.
115
- def self::included( klass )
116
- klass.extend( ClassMethods )
117
- super
118
- end
119
-
120
-
121
- ### Class methods to add to classes with plugins.
122
- module ClassMethods
123
-
124
- ##
125
- # If plugins have already been installed, this will be the call frame
126
- # they were first installed from. This is used to warn about installing
127
- # plugins twice.
128
- attr_accessor :plugins_installed_from
129
-
130
-
131
- ### Returns +true+ if the plugins for the extended app class have already
132
- ### been installed.
133
- def plugins_installed?
134
- return !self.plugins_installed_from.nil?
135
- end
136
-
137
-
138
- ### Extension callback -- add instance variables to extending objects.
139
- def inherited( subclass )
140
- super
141
- @plugins ||= []
142
- subclass.instance_variable_set( :@plugins, @plugins.dup )
143
- subclass.instance_variable_set( :@plugins_installed_from, nil )
144
- end
145
-
146
-
147
- ### Load the plugins with the given +names+ and install them.
148
- def plugins( *names )
149
- Strelka.log.info "Adding plugins: %s" % [ names.flatten.map(&:to_s).join(', ') ]
150
-
151
- # Load the associated Plugin Module objects
152
- names.flatten.each {|name| self.load_plugin(name) }
153
-
154
- # Add the name/s to the list of mixins to apply on startup
155
- @plugins |= names
156
-
157
- # Install the declarative half of the plugin immediately
158
- names.each do |name|
159
- plugin = nil
160
-
161
- if name.is_a?( Module )
162
- plugin = name
163
- else
164
- plugin = Strelka::App.loaded_plugins[ name ]
165
- end
166
-
167
- Strelka.log.debug " registering %p" % [ name ]
168
- self.register_plugin( plugin )
169
- end
170
- end
171
- alias_method :plugin, :plugins
172
-
173
-
174
- ### Load the plugin with the given +name+
175
- def load_plugin( name )
176
-
177
- # Just return Modules as-is
178
- return name if name.is_a?( Strelka::App::Plugin )
179
- mod = Strelka::App.loaded_plugins[ name.to_sym ]
180
-
181
- unless mod.is_a?( Module )
182
- Strelka.log.debug "Loading plugin from strelka/app/#{name}"
183
- require "strelka/app/#{name}"
184
- mod = Strelka::App.loaded_plugins[ name.to_sym ] or
185
- raise "#{name} plugin didn't load correctly."
186
- end
187
-
188
- return mod
189
- end
190
-
191
-
192
- ### Register the plugin +mod+ in the receiving class. This adds any
193
- ### declaratives and class-level data necessary for configuring the
194
- ### plugin.
195
- def register_plugin( mod )
196
- if mod.const_defined?( :ClassMethods )
197
- cm_mod = mod.const_get(:ClassMethods)
198
- Strelka.log.debug " adding class methods from %p" % [ cm_mod ]
199
-
200
- extend( cm_mod )
201
- cm_mod.instance_variables.each do |ivar|
202
- Strelka.log.debug " copying class instance variable %s" % [ ivar ]
203
- ival = cm_mod.instance_variable_get( ivar )
204
-
205
- # Don't duplicate modules/classes or immediates
206
- instance_variable_set( ivar, Strelka::DataUtilities.deep_copy(ival) )
207
- end
208
- end
209
- end
210
-
211
-
212
- ### Install the mixin part of plugins immediately before the first instance
213
- ### is created.
214
- def new( * )
215
- self.install_plugins unless self.plugins_installed?
216
- super
217
- end
218
-
219
-
220
- ### Install the mixin part of the plugin, in the order determined by
221
- ### the plugin registry based on the run_before and run_after specifications
222
- ### of the plugins themselves.
223
- def install_plugins
224
- if self.plugins_installed?
225
- Strelka.log.warn "Plugins were already installed for %p from %p" %
226
- [ self, self.plugins_installed_from ]
227
- Strelka.log.info "I'll attempt to install any new ones, but plugin ordering"
228
- Strelka.log.info "and other functionality might exhibit strange behavior."
229
- else
230
- Strelka.log.info "Installing plugins for %p." % [ self ]
231
- end
232
-
233
- sorted_plugins = Strelka::App.loaded_plugins.tsort.reverse
234
-
235
- sorted_plugins.each do |name|
236
- mod = Strelka::App.loaded_plugins[ name ]
237
-
238
- unless @plugins.include?( name ) || @plugins.include?( mod )
239
- Strelka.log.debug " skipping %s" % [ name ]
240
- next
241
- end
242
-
243
- Strelka.log.info " including %p." % [ mod ]
244
- include( mod )
245
- end
246
-
247
- self.plugins_installed_from = caller( 1 ).first
248
- end
249
-
250
- end # module ClassMethods
251
-
252
-
253
- #
254
- # :section: Extension Points
255
- #
256
-
257
- ### The main extension-point for the plugin system. Strelka::App supers to this method
258
- ### with a block that processes the actual request, and the plugins implement this
259
- ### method to add their own functionality.
260
- def handle_request( request, &block )
261
- raise LocalJumpError,
262
- "no block given; plugin supering without preserving arguments?" unless block
263
- return block.call( request )
264
- end
265
-
266
-
267
- ### An alternate extension-point for the plugin system. Plugins can implement this method
268
- ### to alter or replace the +request+ before the regular request/response cycle begins.
269
- def fixup_request( request )
270
- return request
271
- end
272
-
273
-
274
- ### An alternate extension-point for the plugin system. Plugins can implement this method
275
- ### to alter or replace the +response+ after the regular request/response cycle is finished.
276
- def fixup_response( response )
277
- return response
278
- end
279
-
280
- end # module Plugins
281
-
282
- end # class Strelka::App
283
-
284
-