bootscale 0.5.2 → 0.6.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: 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