nanoc-core 4.11.15 → 4.11.20

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
  SHA256:
3
- metadata.gz: 1d36108ed7c1e713b65fe5119960115a3a8749efb49acb59dca207bdd82e5892
4
- data.tar.gz: d3799629cd606d9cb73aad14f798e2eac3e549149774e374e2a92832a4bc09e4
3
+ metadata.gz: ac94fc2464196846d4d6b38fb9a3ee02d0566aaa16f4f192e63f7989af937dc0
4
+ data.tar.gz: 0ba05d8ccb6d2cb10a8ec2909bb9bd99dee5203272c24cd02fdc6c6d4041dd17
5
5
  SHA512:
6
- metadata.gz: 6aea180789234158ce9d449d922e2bc88b4daf2ba877870eb865cfc0fbae52ac60995439294f2a70bc2c705a248d1dc512431a3df45beda5c4567a8046c06349
7
- data.tar.gz: edd1525adfe8ca4e64a227b6dc57c131a674d6bc56071d0befe29b1c765a97933b76102f5acfbf44c7f130c7b746e5494604183392331f7756170064dfec8cd1
6
+ metadata.gz: b76254a60ba5cc2d94f0dc6a01498b51fa22c068ba6ee93c6434cee1105a29922f664c08090b155b18a9016b065fb854f60dc38a57f2effa6b1a6a1c1d94aeee
7
+ data.tar.gz: 314da571f7e0b49544152e66dc1bc9b30ae49911b0f8aeaf863d23731294ffe33e7b21977a2238f619396119ab6b7a635453e80544ccaf0193e7a94495d34313
@@ -9,6 +9,8 @@ require 'tmpdir'
9
9
  require 'yaml'
10
10
 
11
11
  # External gems
12
+ require 'clonefile'
13
+ require 'concurrent-ruby'
12
14
  require 'json_schema'
13
15
  require 'ddmemoize'
14
16
  require 'ddmetrics'
@@ -50,8 +50,8 @@ module Nanoc
50
50
  end
51
51
 
52
52
  def calc_for_each_attribute_of(obj, digest_class = CompactDigest)
53
- obj.attributes.each_with_object({}) do |(key, value), memo|
54
- memo[key] = Nanoc::Core::Checksummer.calc(value, digest_class)
53
+ obj.attributes.transform_values do |value|
54
+ Nanoc::Core::Checksummer.calc(value, digest_class)
55
55
  end
56
56
  end
57
57
 
@@ -3,6 +3,12 @@
3
3
  module Nanoc
4
4
  module Core
5
5
  class CompilationItemRepView < ::Nanoc::Core::BasicItemRepView
6
+ # How long to wait before the requested file appears.
7
+ #
8
+ # This is a bit of a hack -- ideally, Nanoc would know that the file is
9
+ # being generated, and wait the appropriate amount of time.
10
+ FILE_APPEAR_TIMEOUT = 10.0
11
+
6
12
  # @abstract
7
13
  def item_view_class
8
14
  Nanoc::Core::CompilationItemView
@@ -27,7 +33,7 @@ module Nanoc
27
33
  # Wait for file to exist
28
34
  if res
29
35
  start = Time.now
30
- sleep 0.05 until File.file?(res) || Time.now - start > 1.0
36
+ sleep 0.05 until File.file?(res) || Time.now - start > FILE_APPEAR_TIMEOUT
31
37
  raise Nanoc::Core::Errors::InternalInconsistency, "File did not apear in time: #{res}" unless File.file?(res)
32
38
  end
33
39
 
@@ -32,7 +32,7 @@ module Nanoc
32
32
  end
33
33
 
34
34
  contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
35
- def run(_rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
35
+ def run(_rep, is_outdated:)
36
36
  raise NotImplementedError
37
37
  end
38
38
 
@@ -21,7 +21,7 @@ module Nanoc
21
21
  raise(res)
22
22
  when Proc
23
23
  fiber.resume(res.call)
24
- when DONE # rubocop:disable Lint/EmptyWhen
24
+ when DONE
25
25
  # ignore
26
26
  else
27
27
  raise Nanoc::Core::Errors::InternalInconsistency.new(
@@ -6,45 +6,6 @@ module Nanoc
6
6
  class Write < Abstract
7
7
  include Nanoc::Core::ContractsSupport
8
8
 
9
- class Worker
10
- def initialize(queue:, compiled_content_store:)
11
- @queue = queue
12
- @compiled_content_store = compiled_content_store
13
- end
14
-
15
- def start
16
- @thread = Thread.new do
17
- Thread.current.abort_on_exception = true
18
- Thread.current.priority = -1 # schedule I/O work ASAP
19
-
20
- writer = Nanoc::Core::ItemRepWriter.new
21
-
22
- while rep = @queue.pop # rubocop:disable Lint/AssignmentInCondition
23
- writer.write_all(rep, @compiled_content_store)
24
- end
25
- end
26
- end
27
-
28
- def join
29
- @thread.join
30
- end
31
- end
32
-
33
- class WorkerPool
34
- def initialize(queue:, size:, compiled_content_store:)
35
- @workers = Array.new(size) { Worker.new(queue: queue, compiled_content_store: compiled_content_store) }
36
- end
37
-
38
- def start
39
- @workers.each(&:start)
40
- end
41
-
42
- def join
43
- @workers.each(&:join)
44
- end
45
- end
46
-
47
- QUEUE_SIZE = 40
48
9
  WORKER_POOL_SIZE = 5
49
10
 
50
11
  def initialize(compiled_content_store:, wrapped:)
@@ -52,19 +13,16 @@ module Nanoc
52
13
 
53
14
  @compiled_content_store = compiled_content_store
54
15
 
55
- @queue = SizedQueue.new(QUEUE_SIZE)
56
- @worker_pool = WorkerPool.new(queue: @queue, size: WORKER_POOL_SIZE, compiled_content_store: @compiled_content_store)
57
- end
16
+ @pool = Concurrent::FixedThreadPool.new(WORKER_POOL_SIZE)
58
17
 
59
- def start
60
- super
61
- @worker_pool.start
18
+ @writer = Nanoc::Core::ItemRepWriter.new
62
19
  end
63
20
 
64
21
  def stop
22
+ @pool.shutdown
23
+ @pool.wait_for_termination
24
+
65
25
  super
66
- @queue.close
67
- @worker_pool.join
68
26
  end
69
27
 
70
28
  contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
@@ -76,7 +34,9 @@ module Nanoc
76
34
  # notification happens before the :rep_write_enqueued one.
77
35
  Nanoc::Core::NotificationCenter.post(:rep_write_enqueued, rep)
78
36
 
79
- @queue << rep
37
+ @pool.post do
38
+ @writer.write_all(rep, @compiled_content_store)
39
+ end
80
40
  end
81
41
  end
82
42
  end
@@ -46,8 +46,8 @@ module Nanoc
46
46
  @binary_cache[rep] = content.select { |_key, c| c.binary? }
47
47
  end
48
48
 
49
- def prune(*args)
50
- @wrapped_caches.each { |w| w.prune(*args) }
49
+ def prune(items:)
50
+ @wrapped_caches.each { |w| w.prune(items: items) }
51
51
  end
52
52
 
53
53
  # True if there is cached compiled content available for this item, and
@@ -32,7 +32,7 @@ module Nanoc
32
32
  outdatedness_store: outdatedness_store,
33
33
  }
34
34
 
35
- Nanoc::Core::Compiler.new(site, params)
35
+ Nanoc::Core::Compiler.new(site, **params)
36
36
  end
37
37
 
38
38
  def compiled_content_cache_class
@@ -113,7 +113,7 @@ module Nanoc
113
113
  src_ref = obj2ref(src)
114
114
  dst_ref = obj2ref(dst)
115
115
 
116
- existing_props = Nanoc::Core::DependencyProps.new(@graph.props_for(dst_ref, src_ref) || {})
116
+ existing_props = Nanoc::Core::DependencyProps.new(**(@graph.props_for(dst_ref, src_ref) || {}))
117
117
  new_props = Nanoc::Core::DependencyProps.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
118
118
  props = existing_props.merge(new_props)
119
119
 
@@ -62,11 +62,7 @@ module Nanoc
62
62
 
63
63
  # Write
64
64
  if is_modified
65
- begin
66
- FileUtils.ln(temp_path, raw_path, force: true)
67
- rescue Errno::EXDEV, Errno::EACCES
68
- FileUtils.cp(temp_path, raw_path)
69
- end
65
+ smart_cp(temp_path, raw_path)
70
66
  end
71
67
 
72
68
  item_rep.modified = is_modified
@@ -80,6 +76,26 @@ module Nanoc
80
76
  def temp_filename
81
77
  Nanoc::Core::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR)
82
78
  end
79
+
80
+ def smart_cp(from, to)
81
+ # Try clonefile
82
+ FileUtils.rm_f(to)
83
+ begin
84
+ res = Clonefile.always(from, to)
85
+ return if res
86
+ rescue Clonefile::UnsupportedPlatform, Errno::ENOTSUP, Errno::EXDEV, Errno::EINVAL
87
+ end
88
+
89
+ # Try with hardlink
90
+ begin
91
+ FileUtils.ln(from, to, force: true)
92
+ return
93
+ rescue Errno::EXDEV, Errno::EACCES
94
+ end
95
+
96
+ # Fall back to old-school copy
97
+ FileUtils.cp(from, to)
98
+ end
83
99
  end
84
100
  end
85
101
  end
@@ -14,6 +14,7 @@ module Nanoc
14
14
  def initialize
15
15
  @counts = {}
16
16
  @root_dir = Dir.mktmpdir('nanoc')
17
+ @mutex = Mutex.new
17
18
  end
18
19
 
19
20
  # @param [String] prefix A string prefix to include in the temporary
@@ -21,8 +22,11 @@ module Nanoc
21
22
  #
22
23
  # @return [String] A new unused filename
23
24
  def create(prefix)
24
- count = @counts.fetch(prefix, 0)
25
- @counts[prefix] = count + 1
25
+ count = nil
26
+ @mutex.synchronize do
27
+ count = @counts.fetch(prefix, 0)
28
+ @counts[prefix] = count + 1
29
+ end
26
30
 
27
31
  dirname = File.join(@root_dir, prefix)
28
32
  filename = File.join(@root_dir, prefix, count.to_s)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Nanoc
4
4
  module Core
5
- VERSION = '4.11.15'
5
+ VERSION = '4.11.20'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.15
4
+ version: 4.11.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-07 00:00:00.000000000 Z
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: clonefile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: ddmemoize
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -300,7 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
328
  - !ruby/object:Gem::Version
301
329
  version: '0'
302
330
  requirements: []
303
- rubygems_version: 3.1.2
331
+ rubygems_version: 3.2.2
304
332
  signing_key:
305
333
  specification_version: 4
306
334
  summary: Core of Nanoc