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.
- data.tar.gz.sig +0 -0
- data/ChangeLog +94 -26
- data/Manifest.txt +4 -2
- data/examples/apps/ws-echo +17 -0
- data/lib/strelka/app.rb +26 -24
- data/lib/strelka/app/auth.rb +2 -1
- data/lib/strelka/app/errors.rb +1 -1
- data/lib/strelka/app/filters.rb +1 -1
- data/lib/strelka/app/negotiation.rb +1 -1
- data/lib/strelka/app/parameters.rb +2 -2
- data/lib/strelka/app/restresources.rb +1 -1
- data/lib/strelka/app/routing.rb +3 -2
- data/lib/strelka/app/sessions.rb +3 -3
- data/lib/strelka/app/templating.rb +3 -3
- data/lib/strelka/authprovider.rb +2 -10
- data/lib/strelka/behavior/plugin.rb +3 -3
- data/lib/strelka/httprequest.rb +5 -2
- data/lib/strelka/httprequest/session.rb +3 -2
- data/lib/strelka/httpresponse/session.rb +8 -9
- data/lib/strelka/mixins.rb +15 -0
- data/lib/strelka/plugins.rb +257 -0
- data/lib/strelka/router/default.rb +27 -2
- data/lib/strelka/session.rb +20 -2
- data/lib/strelka/session/db.rb +20 -10
- data/lib/strelka/session/default.rb +41 -18
- data/spec/lib/helpers.rb +1 -1
- data/spec/strelka/app/auth_spec.rb +1 -1
- data/spec/strelka/app/errors_spec.rb +1 -1
- data/spec/strelka/app/filters_spec.rb +1 -1
- data/spec/strelka/app/negotiation_spec.rb +1 -1
- data/spec/strelka/app/parameters_spec.rb +1 -1
- data/spec/strelka/app/restresources_spec.rb +1 -1
- data/spec/strelka/app/routing_spec.rb +4 -1
- data/spec/strelka/app/sessions_spec.rb +63 -17
- data/spec/strelka/app/templating_spec.rb +1 -1
- data/spec/strelka/app_spec.rb +13 -5
- data/spec/strelka/httprequest/session_spec.rb +44 -23
- data/spec/strelka/httprequest_spec.rb +21 -0
- data/spec/strelka/httpresponse/session_spec.rb +143 -0
- data/spec/strelka/{app/plugins_spec.rb → plugins_spec.rb} +64 -53
- data/spec/strelka/router/default_spec.rb +15 -0
- data/spec/strelka/router/exclusive_spec.rb +14 -0
- data/spec/strelka/session/db_spec.rb +11 -0
- data/spec/strelka/session/default_spec.rb +10 -2
- metadata +119 -37
- metadata.gz.sig +0 -0
- data/lib/strelka/app/plugins.rb +0 -284
data/lib/strelka/app/plugins.rb
DELETED
@@ -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
|
-
|