nanoc-core 4.11.16 → 4.11.21

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
  SHA256:
3
- metadata.gz: e814752b0c5e45deadac5a7abc2617b54751c07e003eb4d47a337b2182269058
4
- data.tar.gz: b44273b6e8c13423397af5813b9a5bdd04e784e4a6b6af5d7f098b93bcc5707e
3
+ metadata.gz: a9f63cf9ed0953520b811eb964d1b71cad082bc07f945c5b9c838a3730dc9cc2
4
+ data.tar.gz: 58e44db73eb2a9fdd8959964802b78570e15ddc2e4ae8afd2a5da9161da06c61
5
5
  SHA512:
6
- metadata.gz: 490de94696b555b44091fbfb748fade5faabbd54f8c7261140a3592b232912c81fa7551339e130e8d7f853ae24e7645a97df25506fe3ef6de0725e9cd52a4cc5
7
- data.tar.gz: c404dc2bcd979554da3c44e3cac8c132534021b24d5de43cf9f93c568173c99d16e144940bcef33cbecbe4705fefa13222ce522a432daa0aecf78bb956279140
6
+ metadata.gz: b4d4b9458fc23a57bb961c0ed9ff31dd82b43f243cf92d2c45424efda54d3ccacab16be0fd36805f606958eb9167b6537c178ff23c15947f2a2f667bd9901f40
7
+ data.tar.gz: 4668c6c8188d5c885829421d4d4e3564146f9f935576be13daed38410ca7537781545d2f44f4c3a44fdb1c145d1331baf84526b37732f85cdfb9e1e77ce3ccdd
@@ -9,6 +9,7 @@ require 'tmpdir'
9
9
  require 'yaml'
10
10
 
11
11
  # External gems
12
+ require 'concurrent-ruby'
12
13
  require 'json_schema'
13
14
  require 'ddmemoize'
14
15
  require 'ddmetrics'
@@ -19,6 +20,13 @@ require 'tomlrb'
19
20
  require 'tty-platform'
20
21
  require 'zeitwerk'
21
22
 
23
+ # External gems (optional)
24
+ begin
25
+ require 'clonefile'
26
+ rescue LoadError
27
+ # ignore
28
+ end
29
+
22
30
  module Nanoc
23
31
  module Core
24
32
  # Similar to `nil` except that it can only be compared against using
@@ -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
 
@@ -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
@@ -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,28 @@ 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
+ if defined?(Clonefile)
83
+ FileUtils.rm_f(to)
84
+ begin
85
+ res = Clonefile.always(from, to)
86
+ return if res
87
+ rescue Clonefile::UnsupportedPlatform, Errno::ENOTSUP, Errno::EXDEV, Errno::EINVAL
88
+ end
89
+ end
90
+
91
+ # Try with hardlink
92
+ begin
93
+ FileUtils.ln(from, to, force: true)
94
+ return
95
+ rescue Errno::EXDEV, Errno::EACCES
96
+ end
97
+
98
+ # Fall back to old-school copy
99
+ FileUtils.cp(from, to)
100
+ end
83
101
  end
84
102
  end
85
103
  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.16'
5
+ VERSION = '4.11.21'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.16
4
+ version: 4.11.21
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-04-26 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: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: ddmemoize
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -300,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
314
  - !ruby/object:Gem::Version
301
315
  version: '0'
302
316
  requirements: []
303
- rubygems_version: 3.1.2
317
+ rubygems_version: 3.2.2
304
318
  signing_key:
305
319
  specification_version: 4
306
320
  summary: Core of Nanoc