roda-container 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -1
- data/lib/roda/plugins/container.rb +35 -13
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15d116dc716eb7e2220f95bab7a4179e53737569
|
4
|
+
data.tar.gz: 02779f0dd1d9e5c7c6ab4bec115abd2f65d1d586
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7134e5541427b5da8d8b49f217baccdc3d5063fe6a350ccbf19c09b68167821f97bdc5489d887c4ae032a0749f7c3b46b3d9bea9965dc85f62980cb7ebf6600d
|
7
|
+
data.tar.gz: fcafa937f4f20c140ea30397a28478631381aad60f9a732e49af9e0d6260cbcc26d6568b82bdc344cb0edd9395027fd247dd7a0e1e8537601b83fa7123cb00d0
|
data/README.md
CHANGED
@@ -45,11 +45,43 @@ end
|
|
45
45
|
|
46
46
|
MyApplication.route do |r|
|
47
47
|
# Roda responds to the instance method #call, with the call: false
|
48
|
-
# option, calling MyApplication.resolve(:app) will not attempt to call
|
48
|
+
# option, calling MyApplication.instance.resolve(:app) will not attempt to call
|
49
49
|
# it, without the option, the application would error
|
50
|
+
MyApplication.instance.register(:app, self, call: false)
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
## Thread safety
|
55
|
+
|
56
|
+
Please note the use of `MyApplication.instance.register` and `MyApplication.instance.resolve` above, without the calls to `Roda.instance` there is a high possiblilty of a thread safety issue when registering anything at runtime. For example:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class MyApplication < Roda
|
60
|
+
plugin :container
|
61
|
+
end
|
62
|
+
|
63
|
+
MyApplication.route do |r|
|
64
|
+
# DO NOT DO THIS, SEE ABOVE ^^^
|
50
65
|
MyApplication.register(:app, self, call: false)
|
66
|
+
|
67
|
+
r.on 'users' do
|
68
|
+
# ...
|
69
|
+
r.get :id do |user_id|
|
70
|
+
MyApplication.resolve(:app)
|
71
|
+
end
|
72
|
+
|
73
|
+
r.post do
|
74
|
+
sleep(5)
|
75
|
+
MyApplication.resolve(:app)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
51
79
|
```
|
52
80
|
|
81
|
+
Immagine a user hitting `POST /users`, then another user hitting `GET /users/{id}` in quick succession; the first user registers their instance of app with the container, then hits the 5 second sleep, then the second user comes along, registers their instance of app with the container, the request executes and they go on their merry way.
|
82
|
+
|
83
|
+
A few seconds later the 5 second sleep is complete, and the first user resolves `:app` from the container, only to find the instance that was registered by the user hitting `GET /users/{id}`, they have just spent 5 minutes meticulously filling out your webform to create their user account, only for their payload to lost in a race condition, needless to say, you don't want this to happen.
|
84
|
+
|
53
85
|
## Contributing
|
54
86
|
|
55
87
|
1. Fork it ( https://github.com/AMHOL/roda-container )
|
@@ -31,6 +31,27 @@ class Roda
|
|
31
31
|
# MyApplication.register(:person_repository, -> { PersonRepository.new })
|
32
32
|
# MyApplication.resolve(:person_repository).first
|
33
33
|
module Container
|
34
|
+
class Container < RodaCache
|
35
|
+
def register(key, contents = nil, options = {}, &block)
|
36
|
+
if block_given?
|
37
|
+
item = block
|
38
|
+
options = contents if contents.is_a?(::Hash)
|
39
|
+
else
|
40
|
+
item = contents
|
41
|
+
end
|
42
|
+
|
43
|
+
self[key] = Content.new(item, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def resolve(key)
|
47
|
+
content = fetch(key) do
|
48
|
+
fail ::Roda::ContainerError, "Nothing registered with the name #{key}"
|
49
|
+
end
|
50
|
+
|
51
|
+
content.call
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
34
55
|
class Content
|
35
56
|
attr_reader :item, :options
|
36
57
|
|
@@ -54,7 +75,7 @@ class Roda
|
|
54
75
|
private :container
|
55
76
|
|
56
77
|
def self.extended(subclass)
|
57
|
-
subclass.instance_variable_set(:@container,
|
78
|
+
subclass.instance_variable_set(:@container, Container.new)
|
58
79
|
super
|
59
80
|
end
|
60
81
|
|
@@ -63,28 +84,29 @@ class Roda
|
|
63
84
|
super
|
64
85
|
end
|
65
86
|
|
87
|
+
def instance
|
88
|
+
Thread.current[:__container__]
|
89
|
+
end
|
90
|
+
|
66
91
|
def register(key, contents = nil, options = {}, &block)
|
67
|
-
|
68
|
-
item = block
|
69
|
-
options = contents if contents.is_a?(::Hash)
|
70
|
-
else
|
71
|
-
item = contents
|
72
|
-
end
|
73
|
-
container[key] = Roda::RodaPlugins::Container::Content.new(item, options)
|
92
|
+
container.register(key, contents, options, &block)
|
74
93
|
end
|
75
94
|
|
76
95
|
def resolve(key)
|
77
|
-
|
78
|
-
fail ::Roda::ContainerError, "Nothing registered with the name #{key}"
|
79
|
-
end
|
80
|
-
|
81
|
-
content.call
|
96
|
+
container.resolve(key)
|
82
97
|
end
|
83
98
|
|
84
99
|
def detach_container
|
85
100
|
@container = container.dup
|
86
101
|
end
|
87
102
|
end
|
103
|
+
|
104
|
+
module InstanceMethods
|
105
|
+
def call(*args, &block)
|
106
|
+
Thread.current[:__container__] = self.class.send(:container).dup
|
107
|
+
super
|
108
|
+
end
|
109
|
+
end
|
88
110
|
end
|
89
111
|
|
90
112
|
register_plugin(:container, Container)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda-container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Holland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack-test
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: A plugin for Roda which turns your application into a (IoC) container
|
70
84
|
email:
|
71
85
|
- andyholland1991@aol.com
|