bootscale 0.5.2 → 0.6.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: 8f9aae3eeb86052322d2ae6b745e8c0f0385e2d4
4
- data.tar.gz: 0bbe7af30e7de21a6641771d8571d3f63efb9e1a
3
+ metadata.gz: 18d8250aaa3d20edb7c2d8279f04eb1ec4f87493
4
+ data.tar.gz: f93a4fd4d1369f68b06b616b113f47bbd88f3444
5
5
  SHA512:
6
- metadata.gz: 7a54144b441ef4dd3a233a8d22ce838ff6a3a13d8204a5304bd614bbd2f88b3c415b0ab62f62281e48df3a396ad2470a594387f9312997d5d6748b2d2dce5388
7
- data.tar.gz: 72699fc3cf785bfa26ba3b25917978ec4f109a3b71260f92320d9b6db6f419f378e0550592f3473a5d901c7231cebfa868f0cb259285db87df892852b68336b0
6
+ metadata.gz: c32e0137cd9c339c9e2a4e9eb3bc31f0aff386a924631cf561e28df58d103c38d079719d11e89e2cdc61124d181f34851c874c479b508efa6912fc3310544ce6
7
+ data.tar.gz: 266605dcdcd8bb793ac7cd2719e4a8c3680a611dad42a9d524a6d66737596e7a2233bc70e28e0818ead8b034114e6e02cfdfc1997558362838d87c566e184c2c
data/README.md CHANGED
@@ -14,16 +14,6 @@ but for bigger applications it can save 1 to 3 seconds of boot time per 100 used
14
14
  # Gemfile
15
15
  gem 'bootscale', require: false
16
16
  ```
17
-
18
- Then you need to add right after `require 'bundler/setup'`:
19
-
20
- ```ruby
21
- require 'bundler/setup'
22
- require 'bootscale/setup'
23
- ```
24
-
25
- If your application is a Rails application, you will find this in `config/boot.rb`.
26
-
27
17
  ### Important
28
18
 
29
19
  For correctness cache should be updated everytime `$LOAD_PATH` is modified by calling `Bootscale.regenerate`.
@@ -38,6 +28,22 @@ module MyApp
38
28
  end
39
29
  end
40
30
  end
31
+
32
+ ### Rails applications
33
+
34
+ Locate `require 'bundler/setup'` in `config/boot.rb` and add `require 'bootscale/rails'` after it:
35
+ ```ruby
36
+ require 'bundler/setup'
37
+ require 'bootscale/rails'
38
+ ```
39
+
40
+ ### Other Bundler enabled applications
41
+
42
+ Locate `require 'bundler/setup'`, and add `require 'bootscale/setup'` after it:
43
+
44
+ ```ruby
45
+ require 'bundler/setup'
46
+ require 'bootscale/setup'
41
47
  ```
42
48
 
43
49
  ## Faster cache loading
@@ -51,10 +57,10 @@ gem 'bootscale', require: false
51
57
  ```
52
58
 
53
59
  ```ruby
54
- # config/application.rb (or wherever you have the require of bundler/setup)
60
+ # config/boot.rb (or wherever you have the require of bundler/setup)
55
61
  require 'bundler/setup'
56
62
  require 'msgpack'
57
- require 'bootscale/setup'
63
+ require 'bootscale/setup' # or require 'bootscale/rails'
58
64
  ```
59
65
 
60
66
  ## Under the hood
@@ -66,7 +72,7 @@ Problem outlined in this [talk](https://www.youtube.com/watch?v=kwkbrOwLsZY)
66
72
 
67
73
  ## Troubleshooting
68
74
 
69
- If you're experiencing problems with loading your application and are unable to successfully run `Bootscale.regenerate`, try deleting the `tmp/bootscale` folder.
75
+ If you're experiencing problems with loading your application, especially after moving files around, try deleting the `tmp/bootscale` folder.
70
76
 
71
77
  ## Contributing
72
78
 
@@ -0,0 +1,16 @@
1
+ require 'active_support/dependencies'
2
+
3
+ module ActiveSupport
4
+ module Dependencies
5
+ undef_method :search_for_file
6
+
7
+ # ActiveSupport::Dependencies.search_for_file works pretty much like Kernel#require.
8
+ # It has a load path (AS::Dependencies.autoload_paths) and when it's looking for a file to load
9
+ # it search the load path entries one by one for a match.
10
+ # So just like for Kernel#require, this process is increasingly slow the more load path entries you have,
11
+ # and it can be optimized with exactly the same caching strategy.
12
+ def search_for_file(path)
13
+ ::Bootscale::ActiveSupport.cache[path]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ module Bootscale
2
+ module ActiveSupport
3
+ class Cache < ::Bootscale::Cache
4
+ def load_path
5
+ ::ActiveSupport::Dependencies.autoload_paths
6
+ end
7
+
8
+ # Ideally we'd use a more accurate comparison like `#hash`, unfortunately it's
9
+ # not efficient enough given how much of a hot spot this is.
10
+ # So we assume entries are not mutated or replaced, only added or removed.
11
+ # It is obviously wrong sometimes, and you'll have to manually call Bootscale.regenerate
12
+ def reload(force = true)
13
+ @load_path_size ||= nil
14
+
15
+ if force
16
+ @cache = fetch(load_path)
17
+ @load_path_size = load_path.size
18
+ elsif (size = load_path.size) != @load_path_size
19
+ @cache = fetch(load_path)
20
+ @load_path_size = size
21
+ end
22
+ end
23
+ end
24
+
25
+ class << self
26
+ attr_reader :cache, :cache_directory
27
+
28
+ def cache_builder
29
+ @cache_builder ||= CacheBuilder.new
30
+ end
31
+
32
+ def setup(options = {})
33
+ @cache_directory = options.fetch(:cache_directory, Bootscale.cache_directory)
34
+ require 'active_support/dependencies'
35
+ @cache = Cache.new(cache_directory)
36
+ require_relative 'active_support/core_ext'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'file_storage'
2
+
3
+ module Bootscale
4
+ class Cache
5
+ def initialize(cache_directory = nil)
6
+ @storage = FileStorage.new(cache_directory) if cache_directory
7
+ reload
8
+ end
9
+
10
+ def load_path
11
+ $LOAD_PATH
12
+ end
13
+
14
+ def reload(force = true)
15
+ @cache = fetch(load_path) if force
16
+ end
17
+
18
+ def [](path)
19
+ path = path.to_s
20
+ return if path.start_with?(LEADING_SLASH)
21
+ reload(false)
22
+ if path.end_with?(DOT_RB, DOT_SO)
23
+ @cache[path]
24
+ else
25
+ @cache["#{path}#{DOT_RB}"] || @cache["#{path}#{DOT_SO}"]
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :storage
32
+
33
+ def fetch(load_path)
34
+ load || save(Bootscale.cache_builder.generate(load_path))
35
+ end
36
+
37
+ def load
38
+ return unless storage
39
+ storage.load(load_path)
40
+ end
41
+
42
+ def save(cache)
43
+ return cache unless storage
44
+ storage.dump(load_path, cache)
45
+ cache
46
+ end
47
+ end
48
+ end
@@ -1,20 +1,20 @@
1
1
  module Kernel
2
2
  alias_method :require_without_cache, :require
3
3
  def require(path)
4
- require_without_cache(Bootscale[path] || path)
4
+ require_without_cache(Bootscale.cache[path] || path)
5
5
  end
6
6
  end
7
7
 
8
8
  class << Kernel
9
9
  alias_method :require_without_cache, :require
10
10
  def require(path)
11
- require_without_cache(Bootscale[path] || path)
11
+ require_without_cache(Bootscale.cache[path] || path)
12
12
  end
13
13
  end
14
14
 
15
15
  class Module
16
16
  alias_method :autoload_without_cache, :autoload
17
17
  def autoload(const, path)
18
- autoload_without_cache(const, Bootscale[path] || path)
18
+ autoload_without_cache(const, Bootscale.cache[path] || path)
19
19
  end
20
20
  end
@@ -0,0 +1,3 @@
1
+ require_relative 'setup'
2
+ require_relative 'active_support'
3
+ Bootscale::ActiveSupport.setup
@@ -1,3 +1,3 @@
1
1
  module Bootscale
2
- VERSION = '0.5.2'
2
+ VERSION = '0.6.0'
3
3
  end
data/lib/bootscale.rb CHANGED
@@ -6,55 +6,24 @@ module Bootscale
6
6
  LEADING_SLASH = '/'.freeze
7
7
 
8
8
  class << self
9
- def [](path)
10
- path = path.to_s
11
- return if path.start_with?(LEADING_SLASH)
12
- if path.end_with?(DOT_RB, DOT_SO)
13
- @cache[path]
14
- else
15
- @cache["#{path}#{DOT_RB}"] || @cache["#{path}#{DOT_SO}"]
16
- end
17
- end
18
-
19
- def setup(options = {})
20
- self.cache_directory = options[:cache_directory]
21
- require_relative 'bootscale/core_ext'
22
- regenerate
23
- end
24
-
25
- def regenerate
26
- @cache = load_cache || save_cache(cache_builder.generate($LOAD_PATH))
27
- end
28
-
29
- private
9
+ attr_reader :cache, :cache_directory
30
10
 
31
11
  def cache_builder
32
12
  @cache_builder ||= CacheBuilder.new
33
13
  end
34
14
 
35
- def load_cache
36
- return unless storage
37
- storage.load($LOAD_PATH)
38
- end
39
-
40
- def save_cache(cache)
41
- return cache unless storage
42
- storage.dump($LOAD_PATH, cache)
43
- cache
15
+ def regenerate
16
+ cache.reload
44
17
  end
45
18
 
46
- attr_accessor :storage
47
-
48
- def cache_directory=(directory)
49
- if directory
50
- require_relative 'bootscale/file_storage'
51
- self.storage = FileStorage.new(directory)
52
- else
53
- self.storage = nil
54
- end
19
+ def setup(options = {})
20
+ @cache_directory = options[:cache_directory]
21
+ @cache = Cache.new(cache_directory)
22
+ require_relative 'bootscale/core_ext'
55
23
  end
56
24
  end
57
25
  end
58
26
 
59
27
  require_relative 'bootscale/entry'
60
28
  require_relative 'bootscale/cache_builder'
29
+ require_relative 'bootscale/cache'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootscale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-27 00:00:00.000000000 Z
11
+ date: 2016-12-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Inspired by Aaron Patterson's talk on the subject
14
14
  email:
@@ -20,10 +20,14 @@ files:
20
20
  - LICENSE.txt
21
21
  - README.md
22
22
  - lib/bootscale.rb
23
+ - lib/bootscale/active_support.rb
24
+ - lib/bootscale/active_support/core_ext.rb
25
+ - lib/bootscale/cache.rb
23
26
  - lib/bootscale/cache_builder.rb
24
27
  - lib/bootscale/core_ext.rb
25
28
  - lib/bootscale/entry.rb
26
29
  - lib/bootscale/file_storage.rb
30
+ - lib/bootscale/rails.rb
27
31
  - lib/bootscale/setup.rb
28
32
  - lib/bootscale/utils.rb
29
33
  - lib/bootscale/version.rb