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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -1
  3. data/lib/roda/plugins/container.rb +35 -13
  4. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15f3136a230d1b934b51c0ca18f2c772378deb5f
4
- data.tar.gz: 2ff4e2383eb0e47f4000b97912cc0a7d195b82b6
3
+ metadata.gz: 15d116dc716eb7e2220f95bab7a4179e53737569
4
+ data.tar.gz: 02779f0dd1d9e5c7c6ab4bec115abd2f65d1d586
5
5
  SHA512:
6
- metadata.gz: 88241b79de3a8dcf2f8a801562923e26b9aa9b509156642776eccf280aab2fe2880f5c6c29fca44100149cc1ed425721d9e9ab6cc37cc0b4d4caf3717ebfb61e
7
- data.tar.gz: 52f0ace71d379a143625d95bc2d22f9055f4e3b7eceee7eaecf0668750a540460e1d6dad38272f09ce2d0750ab827567d90e541c2bb689c0da27653e857a6ab1
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, RodaCache.new)
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
- if block_given?
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
- content = container.fetch(key) do
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.3
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-14 00:00:00.000000000 Z
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