fontist 3.0.18 → 3.0.19

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: '0215294c3d206af7354e6fd6f6f4fd0640e0ba68e53c6ef9891d09f646dfc34e'
4
- data.tar.gz: 35757e455e568ec462f7c9fe9347104ac28b87a2b1140fde946847d5aa283fa1
3
+ metadata.gz: 2892a051558c7fca54573398a4d81a65b24365a3a42c2aaedac27f38ed85a70f
4
+ data.tar.gz: d24c202473b5a65e7c282d99802bf5f443d664ca5bceaa61349a912dea2c00bf
5
5
  SHA512:
6
- metadata.gz: cf6667f140b7437998eb2d5ae2828e98ca5265f326a274ac00519d7be8e274c59615a6a0ca7d94b425f58a6327367d6939d4c18783068d785cde2937ee99d32a
7
- data.tar.gz: da9ef27ff12d6d8902f295bca6c8965bcf996f6aeb8a89c63c54b629aca16f34e5f9af8be776509dd35a14594ff7996884e0fc5992f7b4713755f4bb013aba42
6
+ metadata.gz: e8833cb9fc107eaf9b3a3f8d470735d7c269c35a12ecaf69cba222553ec2bd2db20b19e8ee3d9482b0f92127dfbf11ff24808a81e942e471ad52b4e79dc4e032
7
+ data.tar.gz: d72ce09d1cb402e2c35b16116fec1a562e67fb020fd217ce1289ca9784305d15da7fb55fd0e58b90f290b1217fed442b5e7f7aaa060256067d952248eea2c714
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ inherit_from:
3
3
  - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.0
7
7
  SuggestExtensions: false
8
8
 
9
9
  plugins:
data/Gemfile CHANGED
@@ -20,7 +20,8 @@ gem "webmock"
20
20
 
21
21
  # Optional YAML engine (consumer-side dependency; needs Ruby >= 3.0,
22
22
  # which is above fontist's gemspec floor, so it stays out of the
23
- # gemspec). When installed, model YAML parses route through it.
23
+ # gemspec). Activated with FONTIST_YAML=yeptris; off by default
24
+ # pending leptris/yeptris#863 (linux scalar-parity fix).
24
25
  gem "yeptris", require: false
25
26
 
26
27
  # Profiling tools (development only)
data/fontist.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.post_install_message = "Please run `fontist update` to fetch formulas."
17
17
 
18
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
18
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
19
19
 
20
20
  spec.metadata["homepage_uri"] = spec.homepage
21
21
  spec.metadata["source_code_uri"] = "https://github.com/fontist/fontist"
@@ -559,19 +559,48 @@ stats:)
559
559
  verbose: verbose, stats: stats,
560
560
  num_workers: num_cores)
561
561
  else
562
- # Measured on 600 system fonts: single thread 2.3s, 8 threads
563
- # 3.3s (GVL-bound, mutex contention), 8 processes 0.6s. The
564
- # silent build path therefore forks instead of threading
565
- results = Parallel.map(sorted_paths, in_processes: num_cores) do |path|
566
- detect_font_with_cache(path, existing_fonts_by_path[path],
567
- stats: nil)
562
+ # Threads, not forked processes: a silent scan runs from inside
563
+ # long-lived host processes (e.g. metanorma, whose heap reaches
564
+ # hundreds of MB by the time fonts are looked up). Each fork
565
+ # inherits that heap, and its RSS is charged to the process group
566
+ # while it lives, so an 8-process scan transiently multiplies the
567
+ # host's footprint by up to 9x — measured 3.6GB against a 0.9GB
568
+ # parent during a metanorma compile (OOMs under cgroup caps).
569
+ # The ~1s-per-600-fonts scan penalty is bounded and paid only on
570
+ # cache-miss rebuilds. split_paths_by_reuse keeps cached entries
571
+ # in the parent: see its comment for the marshal constraint.
572
+ to_scan, cached_results = split_paths_by_reuse(
573
+ sorted_paths,
574
+ existing_fonts_by_path)
575
+
576
+ results = Parallel.map(to_scan, in_threads: num_cores) do |path|
577
+ detect_fonts(path, stats: nil)
568
578
  end.flatten.compact
569
579
 
570
- stats&.total_fonts = results.size
571
- results
580
+ stats&.total_fonts = cached_results.size + results.size
581
+ cached_results + results
572
582
  end
573
583
  end
574
584
 
585
+ # The stat-only reuse check runs in the parent: cached entries can
586
+ # carry backrefs to their SystemIndexFontCollection (whose
587
+ # paths_loader is a Proc), and worker results are Marshal.dump'ed
588
+ # back across the fork boundary — crossing it with cached
589
+ # collections raises "no _dump_data is defined for class Proc".
590
+ # Workers therefore receive only to-scan paths, and the block
591
+ # handed to Parallel closes over nothing but its argument.
592
+ def split_paths_by_reuse(sorted_paths, existing_fonts_by_path)
593
+ unchanged, to_scan = sorted_paths.partition do |path|
594
+ cached = existing_fonts_by_path[path]
595
+ cached&.any? && file_unchanged?(path, cached.first)
596
+ end
597
+ cached_results = unchanged.flat_map do |path|
598
+ existing_fonts_by_path[path].to_a
599
+ end
600
+
601
+ [to_scan, cached_results]
602
+ end
603
+
575
604
  def process_paths_in_threads(sorted_paths, existing_fonts_by_path,
576
605
  verbose:, stats:, num_workers:)
577
606
  progress = ScanProgress.new(sorted_paths.size, verbose: verbose) do |count, path|
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "3.0.18".freeze
2
+ VERSION = "3.0.19".freeze
3
3
  end
@@ -3,20 +3,21 @@
3
3
  module Fontist
4
4
  # Model YAML engine selection.
5
5
  #
6
- # When the yeptris gem is available, model YAML (formula and index
7
- # documents, via lutaml-model) is parsed through its native loader -
8
- # measured 4x faster than Psych on those artifacts. The gem is an
9
- # optional consumer-side dependency (it needs Ruby >= 3.0, above
10
- # fontist's floor), so absence falls back to Psych silently.
11
- # FONTIST_YAML=psych forces the standard engine.
6
+ # The yeptris engine (native loader, measured 4x faster than Psych on
7
+ # large documents) activates only when explicitly enabled with
8
+ # FONTIST_YAML=yeptris. It is off by default because the yeptris
9
+ # x86_64-linux and Windows builds currently mis-parse some plain
10
+ # scalars as single-element Arrays (leptris/yeptris#863); flip the
11
+ # default once that parity fix lands.
12
12
  module YamlBackend
13
13
  ENV_KEY = "FONTIST_YAML"
14
+ ENABLED_VALUE = "yeptris"
14
15
 
15
16
  class << self
16
17
  # Returns the activated adapter class, or nil when the standard
17
- # engine stays in place (flag set, or yeptris unavailable)
18
+ # engine stays in place (flag unset, or yeptris unavailable)
18
19
  def activate!
19
- return nil if forced_standard?
20
+ return nil unless enabled?
20
21
  return nil unless yeptris_available?
21
22
 
22
23
  adapter = Yaml::YeptrisAdapter
@@ -25,8 +26,8 @@ module Fontist
25
26
  adapter
26
27
  end
27
28
 
28
- def forced_standard?
29
- ENV[ENV_KEY] == "psych"
29
+ def enabled?
30
+ ENV[ENV_KEY] == ENABLED_VALUE
30
31
  end
31
32
 
32
33
  def yeptris_available?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontist
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.18
4
+ version: 3.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -536,7 +536,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
536
536
  requirements:
537
537
  - - ">="
538
538
  - !ruby/object:Gem::Version
539
- version: 2.7.0
539
+ version: 3.0.0
540
540
  required_rubygems_version: !ruby/object:Gem::Requirement
541
541
  requirements:
542
542
  - - ">="