viaduct 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +6 -0
- data/Guardfile +1 -1
- data/LICENSE +2 -2
- data/README.md +87 -7
- data/lib/viaduct/runner.rb +3 -6
- data/lib/viaduct/version.rb +1 -1
- data/lib/viaduct/warden.rb +1 -1
- data/spec/integration_spec.rb +64 -0
- data/spec/runner_spec.rb +1 -23
- data/viaduct.gemspec +0 -4
- metadata +8 -53
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2010-
|
3
|
+
Copyright (c) 2010-2012 Mitchell Hashimoto and John Bender
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Viaduct
|
2
2
|
|
3
|
-
|
3
|
+
Use middleware in your application. Catch exceptions and walk back up the stack!
|
4
|
+
|
5
|
+
Mitchell also created the [middlware](https://github.com/mitchellh/middleware) gem, but it did not contain the warden code which is what interested me the most. Thus, viaduct.
|
4
6
|
|
5
|
-
|
7
|
+
* Source: [https://github.com/slack/viaduct](https://github.com/slack/viaduct)
|
6
8
|
|
7
|
-
Extracted from
|
9
|
+
Extracted from Mitchell Hashimoto and John Bender's very excellent [Vagrant](http://vagrantup.com).
|
8
10
|
|
9
11
|
## Installation
|
10
12
|
|
@@ -20,21 +22,99 @@ Or install it yourself as:
|
|
20
22
|
|
21
23
|
$ gem install viaduct
|
22
24
|
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
If you've spent any time using [rack](http://rack.github.io/) Viaduct will be very familiar.
|
28
|
+
|
29
|
+
Simply:
|
30
|
+
|
31
|
+
1. Define middlware classes that respond to `new` and `call`
|
32
|
+
2. Create your middleware stack with `Viaduct::Builder`
|
33
|
+
3. Run your stack with `Viaduct::Runner`
|
34
|
+
|
35
|
+
For a few examples see the [integration example spec](spec/integration_spec.rb).
|
36
|
+
|
37
|
+
Let's define two middlewares, one that appends text to the environment and one that removes an element.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Add
|
41
|
+
def initialize(app, env)
|
42
|
+
@app, @env = app, env
|
43
|
+
end
|
44
|
+
|
45
|
+
def call(env)
|
46
|
+
env[:data] << "adding"
|
47
|
+
@app.call(env)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Remove
|
52
|
+
def initialize(app, env)
|
53
|
+
@app, @env = app, env
|
54
|
+
end
|
55
|
+
|
56
|
+
def call(env)
|
57
|
+
env[:data].shift
|
58
|
+
@app.call(env)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Organize these into a sequence:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
stack = Viaduct::Builder.new do
|
67
|
+
use Add
|
68
|
+
use Remove
|
69
|
+
use Add
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
Then execute that sequence by calling `Viaduct::Runner.run`:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
env = { data: [] }
|
77
|
+
result = Viaduct::Runner.run(stack, env})
|
78
|
+
#=> { data: ['adding'] }
|
79
|
+
```
|
80
|
+
|
81
|
+
### Handling exceptions
|
82
|
+
|
83
|
+
`Viaduct::Runner` is responsible for the execution of your sequence. The first argument to `run` should be either a sequence from `Viaduct::Builder` or a ruby class that responds to `call`.
|
84
|
+
|
85
|
+
Runner will hand the `env` hash to each of your middlwares, handling any excpetions. In the event that any down-stream middlware raises, Viaduct will walk back up the stack calling `recover` on each middleware see [handling exceptions example](spec/integration_spec.rb).
|
86
|
+
|
87
|
+
### Debugging
|
88
|
+
|
89
|
+
If you pass in an instance of `Logger` to `Viaduct::Runner` (or something that looks like a logger) Viaduct will add happily log execution information:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
sequence = Viaduct::Builder.new do
|
93
|
+
use Robust
|
94
|
+
use Flaky
|
95
|
+
end
|
96
|
+
|
97
|
+
Viaduct::Runner.run(sequence, logger: Logger.new($stderr))
|
98
|
+
#I, [2013-04-19T22:28:29.931249 #847] INFO -- : Calling action: #<Robust:0x007fb20255bf98>
|
99
|
+
#I, [2013-04-19T22:28:29.931329 #847] INFO -- : Calling action: #<Flaky:0x007fb20255bf48>
|
100
|
+
#E, [2013-04-19T22:28:29.931404 #847] ERROR -- : Error occurred: I'm having trouble
|
101
|
+
#I, [2013-04-19T22:28:29.931441 #847] INFO -- : Calling recover: #<Robust:0x007fb20255bf98>
|
102
|
+
#E, [2013-04-19T22:28:29.931488 #847] ERROR -- : Error occurred: I'm having trouble
|
103
|
+
```
|
104
|
+
|
23
105
|
## Tests
|
24
106
|
|
25
|
-
|
107
|
+
$ bundle exec rake
|
26
108
|
|
27
109
|
Or automatically run tests with guard
|
28
110
|
|
29
|
-
|
111
|
+
$ bundle exec guard
|
30
112
|
|
31
113
|
## Releasing
|
32
114
|
|
33
115
|
$ gem install gem-release
|
34
116
|
$ gem bump -trv patch
|
35
117
|
|
36
|
-
## Usage
|
37
|
-
|
38
118
|
## Contributing
|
39
119
|
|
40
120
|
1. Fork it
|
data/lib/viaduct/runner.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
module Viaduct
|
2
2
|
class Runner
|
3
|
-
def
|
4
|
-
|
5
|
-
@lazy_globals = block
|
3
|
+
def self.run(app, options=nil)
|
4
|
+
new.run(app, options)
|
6
5
|
end
|
7
6
|
|
8
7
|
def run(callable_id, options=nil)
|
9
8
|
callable = callable_id
|
10
9
|
callable = Builder.new.use(callable_id) if callable_id.kind_of?(Class)
|
11
|
-
raise ArgumentError, "Argument to run must be a callable object or
|
10
|
+
raise ArgumentError, "Argument to run must be a callable object or known class." if !callable || !callable.respond_to?(:call)
|
12
11
|
|
13
12
|
# Create the initial environment with the options given
|
14
13
|
environment = Environment.new
|
15
|
-
environment.merge!(@globals)
|
16
|
-
environment.merge!(@lazy_globals.call) if @lazy_globals
|
17
14
|
environment.merge!(options || {})
|
18
15
|
|
19
16
|
callable.call(environment)
|
data/lib/viaduct/version.rb
CHANGED
data/lib/viaduct/warden.rb
CHANGED
@@ -17,7 +17,7 @@ module Viaduct
|
|
17
17
|
def initialize(actions, env)
|
18
18
|
@stack = []
|
19
19
|
@actions = actions.map { |m| finalize_action(m, env) }
|
20
|
-
@logger = env.has_key?(:logger) ? env[:logger] : Logger.new(
|
20
|
+
@logger = env.has_key?(:logger) ? env[:logger] : Logger.new(nil)
|
21
21
|
end
|
22
22
|
|
23
23
|
def call(env)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "a simple set of middlwares" do
|
4
|
+
class Add
|
5
|
+
def initialize(app, env); @app, @env = app, env; end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
env[:data] << "adding"
|
9
|
+
@app.call(env)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Remove
|
14
|
+
def initialize(app, env); @app, @env = app, env; end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
env[:data].shift
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "works" do
|
23
|
+
stack = Viaduct::Builder.new do
|
24
|
+
use Add
|
25
|
+
use Remove
|
26
|
+
use Add
|
27
|
+
end
|
28
|
+
|
29
|
+
env = Viaduct::Runner.run(stack, {data: []})
|
30
|
+
env[:data].should == ['adding']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "handling exceptions" do
|
35
|
+
class Robust
|
36
|
+
def initialize(app, env); @app, @env = app, env; end
|
37
|
+
|
38
|
+
def call(env)
|
39
|
+
@app.call(env)
|
40
|
+
end
|
41
|
+
|
42
|
+
def recover(env)
|
43
|
+
env[:logger].error "I got this!"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Flaky
|
48
|
+
class OMG < StandardError; end
|
49
|
+
|
50
|
+
def initialize(app, env); @app, @env = app, env; end
|
51
|
+
|
52
|
+
def call(env)
|
53
|
+
raise OMG.new("I'm having trouble")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:sequence) { Viaduct::Builder.new { use Robust; use Flaky } }
|
58
|
+
|
59
|
+
it "has a chance to handle exceptions" do
|
60
|
+
expect {
|
61
|
+
Viaduct::Runner.run(sequence, { logger: Logger.new(nil) })
|
62
|
+
}.to raise_error Flaky::OMG
|
63
|
+
end
|
64
|
+
end
|
data/spec/runner_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Viaduct::Runner do
|
4
|
-
let(:instance) {
|
4
|
+
let(:instance) { Viaduct::Runner.new }
|
5
5
|
|
6
6
|
it "should raise an error if an invalid callable is given" do
|
7
7
|
expect { instance.run(7) }.to raise_error(ArgumentError, /must be a callable/)
|
@@ -34,26 +34,4 @@ describe Viaduct::Runner do
|
|
34
34
|
instance.run(callable, "data" => "foo")
|
35
35
|
result.should == "foo"
|
36
36
|
end
|
37
|
-
|
38
|
-
it "should pass global options into the hash" do
|
39
|
-
result = nil
|
40
|
-
callable = lambda do |env|
|
41
|
-
result = env["data"]
|
42
|
-
end
|
43
|
-
|
44
|
-
instance = described_class.new("data" => "bar")
|
45
|
-
instance.run(callable)
|
46
|
-
result.should == "bar"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should yield the block passed to the init method to get lazy loaded globals" do
|
50
|
-
result = nil
|
51
|
-
callable = lambda do |env|
|
52
|
-
result = env["data"]
|
53
|
-
end
|
54
|
-
|
55
|
-
instance = described_class.new { { "data" => "bar" } }
|
56
|
-
instance.run(callable)
|
57
|
-
result.should == "bar"
|
58
|
-
end
|
59
37
|
end
|
data/viaduct.gemspec
CHANGED
@@ -16,8 +16,4 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
-
|
20
|
-
gem.add_development_dependency "rake"
|
21
|
-
gem.add_development_dependency "guard"
|
22
|
-
gem.add_development_dependency "rspec", "~> 2.10.0"
|
23
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: viaduct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,56 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rake
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: guard
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: '0'
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: rspec
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 2.10.0
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.10.0
|
12
|
+
date: 2013-04-20 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
62
14
|
description: Build stuff with middlware.
|
63
15
|
email:
|
64
16
|
- jhansen@slack.io
|
@@ -83,6 +35,7 @@ files:
|
|
83
35
|
- lib/viaduct/warden.rb
|
84
36
|
- spec/builder_spec.rb
|
85
37
|
- spec/environment_spec.rb
|
38
|
+
- spec/integration_spec.rb
|
86
39
|
- spec/runner_spec.rb
|
87
40
|
- spec/spec_helper.rb
|
88
41
|
- spec/warden_spec.rb
|
@@ -94,17 +47,17 @@ rdoc_options: []
|
|
94
47
|
require_paths:
|
95
48
|
- lib
|
96
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
50
|
requirements:
|
99
51
|
- - ! '>='
|
100
52
|
- !ruby/object:Gem::Version
|
101
53
|
version: '0'
|
102
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
54
|
none: false
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
56
|
requirements:
|
105
57
|
- - ! '>='
|
106
58
|
- !ruby/object:Gem::Version
|
107
59
|
version: '0'
|
60
|
+
none: false
|
108
61
|
requirements: []
|
109
62
|
rubyforge_project:
|
110
63
|
rubygems_version: 1.8.24
|
@@ -114,6 +67,8 @@ summary: Extracted from vagrant, viaduct makes it easy to build up middlware.
|
|
114
67
|
test_files:
|
115
68
|
- spec/builder_spec.rb
|
116
69
|
- spec/environment_spec.rb
|
70
|
+
- spec/integration_spec.rb
|
117
71
|
- spec/runner_spec.rb
|
118
72
|
- spec/spec_helper.rb
|
119
73
|
- spec/warden_spec.rb
|
74
|
+
has_rdoc:
|