auto_reloader 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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.