roda-container 0.0.3 → 0.0.4

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.
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