auto_reloader 0.3.0 → 0.4.0

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: b42889c4bcc15ca1ea692a102bcb218407d0c035
4
- data.tar.gz: 691c8f940b95e40ecb067b51d86bcd7f479589d0
3
+ metadata.gz: 3e68a0ebbf63e459d5a910ec3a989a23967ee950
4
+ data.tar.gz: 9a92639f3c1d818f35bcce6bcf7d51d1e5c1aa6e
5
5
  SHA512:
6
- metadata.gz: d5bfbc0440e93e598cd4c433564e570bdfcfc7b0d9e37aa7aad9bf14135b5ba0b25a9a1b2478729a937654373a736701428c654125bb9e6e5d51a3f2c8de9130
7
- data.tar.gz: 23ba39d8a90edb4b96da5facb262bba884f02a86aa6be21271230e24d580c9735ec78444dd13fb99360da88265ca119010821dfbda62874f9d98fb7a09db2e82
6
+ metadata.gz: ef00d96db1f52fcf5e36776b8b0fbb0ceeba146440a4eae3ac11a19f7750a7a99907fce687e2442a80647d6992955e69534c4e9db9317b1eed4f04c4889f1feb
7
+ data.tar.gz: 0b025c02a9ddc94bb2e23db839cb079e112d89bc577152ab4a5d327d528e66c520deb9513da7ee333b0541f82e06d2652ff33f8bff33aee97e3693aecce43a18
data/README.md CHANGED
@@ -98,6 +98,12 @@ encouraged to call `AutoReloader.sync_require!`. Or pass `sync_require: true` to
98
98
  The sync behavior will ensure no race conditions that would break the automatic detection
99
99
  mechanism would ever happen.
100
100
 
101
+ Also, it may be dangerous to unload classes while some requests are being processed. So, since
102
+ version 0.4, the default is to await for all blocks executed by `reload!` to finish running before
103
+ unloading. In case you prefer the old behavior because some requests may never return, which
104
+ could happen with some implementations of websocket connections handled by the same process
105
+ for example, just set the `await_before_unload` to `false` on `activate` or `reload!` calls.
106
+
101
107
  ## Known Caveats
102
108
 
103
109
  In order to work transparently AutoReloader will override `require` and `require_relative` when
@@ -12,7 +12,12 @@ class AutoReloader
12
12
  include Singleton
13
13
  extend SingleForwardable
14
14
 
15
- attr_reader :reloadable_paths, :default_onchange, :default_delay
15
+ # default_await_before_unload will await for all calls to reload! to finish before calling
16
+ # unload!. This behavior is usually desired in web applications to avoid unloading anything
17
+ # while a request hasn't been finished, however it won't work fine if some requests are
18
+ # supposed to remain open, like websockets connections or something like that.
19
+
20
+ attr_reader :reloadable_paths, :default_onchange, :default_delay, :default_await_before_unload
16
21
 
17
22
  def_delegators :instance, :activate, :reload!, :reloadable_paths, :reloadable_paths=,
18
23
  :unload!, :force_next_reload, :sync_require!, :async_require!
@@ -35,14 +40,17 @@ class AutoReloader
35
40
 
36
41
  ActivatedMoreThanOnce = Class.new RuntimeError
37
42
  def activate(reloadable_paths: [], onchange: true, delay: nil, watch_paths: nil,
38
- watch_latency: 1, sync_require: false)
43
+ watch_latency: 1, sync_require: false, await_before_unload: true)
39
44
  @activate_lock.synchronize do
40
45
  raise ActivatedMoreThanOnce, 'Can only activate Autoreloader once' if @reloadable_paths
41
46
  @default_delay = delay
42
47
  @default_onchange = onchange
48
+ @default_await_before_unload = await_before_unload
43
49
  @watch_latency = watch_latency
44
50
  sync_require! if sync_require
45
51
  @reload_lock = Mutex.new
52
+ @zero_requests_condition = ConditionVariable.new
53
+ @requests_count = 0
46
54
  @top_level_consts_stack = []
47
55
  @unload_constants = Set.new
48
56
  @unload_files = Set.new
@@ -118,16 +126,30 @@ class AutoReloader
118
126
  end
119
127
 
120
128
  InvalidUsage = Class.new RuntimeError
121
- def reload!(delay: default_delay, onchange: default_onchange, watch_paths: @watch_paths)
129
+ def reload!(delay: default_delay, onchange: default_onchange, watch_paths: @watch_paths,
130
+ await_before_unload: default_await_before_unload)
122
131
  if onchange && !block_given?
123
132
  raise InvalidUsage, 'A block must be provided to reload! when onchange is true (the default)'
124
133
  end
125
134
 
126
- unload! unless reload_ignored = ignore_reload?(delay, onchange, watch_paths)
135
+ unless reload_ignored = ignore_reload?(delay, onchange, watch_paths)
136
+ @reload_lock.synchronize do
137
+ @zero_requests_condition.wait(@reload_lock) unless @requests_count == 0
138
+ end if await_before_unload && block_given?
139
+ unload!
140
+ end
127
141
 
128
142
  result = nil
129
143
  if block_given?
130
- result = yield
144
+ @reload_lock.synchronize{ @requests_count += 1 }
145
+ begin
146
+ result = yield
147
+ ensure
148
+ @reload_lock.synchronize{
149
+ @requests_count -= 1
150
+ @zero_requests_condition.signal if @requests_count == 0
151
+ }
152
+ end
131
153
  find_mtime
132
154
  end
133
155
  @last_reloaded = clock_time if delay
@@ -1,3 +1,3 @@
1
1
  class AutoReloader
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auto_reloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Rosenfeld Rosas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-09 00:00:00.000000000 Z
11
+ date: 2017-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  version: '0'
106
106
  requirements: []
107
107
  rubyforge_project:
108
- rubygems_version: 2.5.1
108
+ rubygems_version: 2.6.8
109
109
  signing_key:
110
110
  specification_version: 4
111
111
  summary: A transparent code reloader.