modware 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 89d92353fe1c300cb4eab370fa9838b6d104e8a6
4
- data.tar.gz: 5d0f202e063fd925a3d57a663e7bcc54548f707b
3
+ metadata.gz: 3954be9354da6c601d61ef054899259b7fc749c9
4
+ data.tar.gz: 6840f5fa4aad0fbd2f4a97200133e12a5362bb25
5
5
  SHA512:
6
- metadata.gz: 24ac95fc4d539362292a322a92f9d7111671d7fd76fcc312f4b9494b27e26c1d113d110286eeb1c8899d835b02cafa61ca189c20ff2069d4b4d2a34aaae1fbd9
7
- data.tar.gz: ca9b22dc6012180c1a109ae2713855d5866bc1969ba75b41a4141074b96ac6668f722084bf7d2d36595662668779b282481ccfe88b4d5621f99c418a1fc1fd18
6
+ metadata.gz: 997889d2b9aed15eabab7ebc41f85f52ba1be4213d2cdcd44ab562ce5245c75c6a3b0d9e87515b02b4387eea34e2305c8c841ee93324c8b76319953f4ab2f803
7
+ data.tar.gz: 0cfe6a6036f066df4794e96944ac42750f4249d1d4a13da5482412fd63cc9bd051de7e7a7f419cc9c67805cec360ee8eb53bfa104f29c18935c2828599e9887f
data/README.md CHANGED
@@ -38,7 +38,7 @@ and Modware will define a class that accepts those keys as keyword arguments, an
38
38
 
39
39
  ### Defining middleware
40
40
 
41
- Middleware is defined as a module that defines one or more middleware methods:
41
+ Define middleware by creating a module that defines one or more of these middleware methods:
42
42
 
43
43
  ```ruby
44
44
  module MyMiddleware
@@ -91,7 +91,36 @@ The execution sequence of the stack is as follows:
91
91
  2. Call each middleware `before(env)` method, in the order they were added
92
92
  3. Call each middleware `around(env)` method, in the order they were added. This bottoms out with the last `implement(env)` method to be added, if any, otherwise the base implementation
93
93
  4. Call each middleware `after(env)` method, in the order they were added
94
- 5. Return `env`
94
+ 5. `stack.start` returns `env`
95
+
96
+ #### Example: wrapping an existing operation
97
+
98
+ A common idiom is to wrap a modware stack around an existing operation:
99
+
100
+ ```ruby
101
+ class WrapsOperation < BaseClass
102
+
103
+ attr_reader :stack
104
+
105
+ def initialized(*args)
106
+ super
107
+ @stack = Modware::Stack.new(env: [:time, :place, :result])
108
+ end
109
+
110
+ def operation(time, place)
111
+ stack.start(time: time, place: place) { |env|
112
+ env.result = super env.time, env.place
113
+ }.result
114
+ end
115
+ end
116
+ ```
117
+
118
+ Notice in the `operation` wrapper method:
119
+
120
+ * The `env` instance gets initialized with the method arguments
121
+ * The base implmenetation of `operation` gets its arguments from the `env` instance, giving clients a chance to modify them in `:before` or `:around` methods.
122
+ * The result of the base implementation gets stored in `env`, giving clients a chance to modify it in `:around` or `:after` methods.
123
+ * When stack execution finishes, it returns `env`, from which the wrapper returns the result.
95
124
 
96
125
  ### Helpers
97
126
 
@@ -101,6 +130,11 @@ The execution sequence of the stack is as follows:
101
130
 
102
131
  The [middleware](https://rubygems.org/gems/middleware) gem works well, following a [rack](http://rack.github.io/)-like execution model.
103
132
 
133
+ ## Change Log
134
+
135
+ * 0.1.1 - Thread safety in Stack#start
136
+ * 0.1.0 - Initial release
137
+
104
138
  ## Contributing
105
139
 
106
140
  Contributions welcome -- feel free to open issues or submit pull requests. Thanks!
data/lib/modware/stack.rb CHANGED
@@ -19,32 +19,31 @@ module Modware
19
19
 
20
20
  def start(*args, &implementation)
21
21
  env = @env_klass.new(*args)
22
- @base_implementation = implementation
23
- execute_stack(env)
22
+ execute_stack(env, implementation)
24
23
  env
25
24
  end
26
25
 
27
26
  private
28
27
 
29
- def execute_stack(env)
30
- return call_implementation(env) unless @middlewares.any?
28
+ def execute_stack(env, base_implementation)
29
+ return call_implementation(env, base_implementation) unless @middlewares.any?
31
30
 
32
31
  @middlewares.each do |middleware|
33
32
  middleware.before env if middleware.respond_to? :before
34
33
  end
35
34
 
36
- @middlewares.first._call(env)
35
+ @middlewares.first._call(env, base_implementation)
37
36
 
38
37
  @middlewares.each do |middleware|
39
38
  middleware.after env if middleware.respond_to? :after
40
39
  end
41
40
  end
42
41
 
43
- def call_implementation(env)
42
+ def call_implementation(env, base_implementation)
44
43
  if middleware = @middlewares.select(&it.respond_to?(:implement)).last
45
44
  middleware.implement(env)
46
- elsif @base_implementation
47
- @base_implementation.call env
45
+ elsif base_implementation
46
+ base_implementation.call env
48
47
  else
49
48
  raise StackError, "No base implementation nor middleware implementation in stack"
50
49
  end
@@ -58,21 +57,21 @@ module Modware
58
57
  singleton_class.send :include, mod
59
58
  end
60
59
 
61
- def _call(env)
60
+ def _call(env, base_implementation)
62
61
  if respond_to? :around
63
62
  around(env) { |env|
64
- _continue env
63
+ _continue env, base_implementation
65
64
  }
66
65
  else
67
- _continue env
66
+ _continue env, base_implementation
68
67
  end
69
68
  end
70
69
 
71
- def _continue(env)
70
+ def _continue(env, base_implementation)
72
71
  if self._next
73
- self._next._call(env)
72
+ self._next._call(env, base_implementation)
74
73
  else
75
- @stack.send :call_implementation, env
74
+ @stack.send :call_implementation, env, base_implementation
76
75
  end
77
76
  end
78
77
  end
@@ -1,3 +1,3 @@
1
1
  module Modware
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modware
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ronen barzel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-09 00:00:00.000000000 Z
11
+ date: 2015-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: key_struct
@@ -179,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
179
  version: '0'
180
180
  requirements: []
181
181
  rubyforge_project:
182
- rubygems_version: 2.2.2
182
+ rubygems_version: 2.4.6
183
183
  signing_key:
184
184
  specification_version: 4
185
185
  summary: A middleware library, featuring a simple interface and "callback" style semantics