Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/solargraph/doc_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ class DocMap

# @return [Array<Gem::Specification>]
def uncached_gemspecs
(uncached_yard_gemspecs + uncached_rbs_collection_gemspecs).sort.
uniq { |gemspec| "#{gemspec.name}:#{gemspec.version}" }
uncached_yard_gemspecs.concat(uncached_rbs_collection_gemspecs)
.sort
.uniq { |gemspec| "#{gemspec.name}:#{gemspec.version}" }
end

# @return [Array<Gem::Specification>]
Expand Down
54 changes: 39 additions & 15 deletions lib/solargraph/library.rb
Original file line number Diff line number Diff line change
Expand Up @@ -588,29 +588,53 @@ def cache_errors
# @return [void]
def cache_next_gemspec
return if @cache_progress
spec = (api_map.uncached_yard_gemspecs + api_map.uncached_rbs_collection_gemspecs).
find { |spec| !cache_errors.include?(spec) }

spec = cacheable_specs.first
return end_cache_progress unless spec

pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
logger.info "Caching #{spec.name} #{spec.version}"
Thread.new do
cache_pid = Process.spawn(workspace.command_path, 'cache', spec.name, spec.version.to_s)
report_cache_progress spec.name, pending
Process.wait(cache_pid)
logger.info "Cached #{spec.name} #{spec.version}"
rescue Errno::EINVAL => _e
logger.info "Cached #{spec.name} #{spec.version} with EINVAL"
rescue StandardError => e
cache_errors.add spec
Solargraph.logger.warn "Error caching gemspec #{spec.name} #{spec.version}: [#{e.class}] #{e.message}"
ensure
end_cache_progress

if Yardoc.processing?(spec)
logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
queued_gemspec_cache.push(spec)
return if pending - queued_gemspec_cache.length < 1

catalog
sync_catalog
else
logger.info "Caching #{spec.name} #{spec.version}"
Thread.new do
cache_pid = Process.spawn(workspace.command_path, 'cache', spec.name, spec.version.to_s)
report_cache_progress spec.name, pending
Process.wait(cache_pid)
logger.info "Cached #{spec.name} #{spec.version}"
rescue Errno::EINVAL => _e
logger.info "Cached #{spec.name} #{spec.version} with EINVAL"
rescue StandardError => e
cache_errors.add spec
Solargraph.logger.warn "Error caching gemspec #{spec.name} #{spec.version}: [#{e.class}] #{e.message}"
ensure
end_cache_progress
catalog
sync_catalog
end
end
end

def cacheable_specs
cacheable = api_map.uncached_yard_gemspecs +
api_map.uncached_rbs_collection_gemspecs -
queued_gemspec_cache -
cache_errors.to_a
return cacheable unless cacheable.empty?

queued_gemspec_cache
end

def queued_gemspec_cache
@queued_gemspec_cache ||= []
end

# @param gem_name [String]
# @param pending [Integer]
# @return [void]
Expand Down
7 changes: 7 additions & 0 deletions lib/solargraph/yardoc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ def cached?(gemspec)
File.exist?(yardoc)
end

# True if another process is currently building the yardoc cache.
#
def processing?(gemspec)
yardoc = File.join(PinCache.yardoc_path(gemspec), 'processing')
File.exist?(yardoc)
end

# Load a gem's yardoc and return its code objects.
#
# @note This method modifies the global YARD registry.
Expand Down