Use posix-spawn to spawn childprocess with timeout of 10 (configurable) seconds

pull/6574/head
Oliver Günther 6 years ago
parent e5625bbc36
commit fcafcd5708
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 3
      Gemfile
  2. 2
      Gemfile.lock
  3. 18
      lib/open_project/text_formatting/formats/markdown/pandoc_wrapper.rb
  4. 10
      lib/open_project/text_formatting/formats/markdown/textile_converter.rb

@ -95,6 +95,9 @@ gem 'ruby-duration', '~> 3.2.0'
# provide compatible filesystem information for available storage
gem 'sys-filesystem', '~> 1.1.4', require: false
# Faster posix-compliant spawns for 8.0. conversions with pandoc
gem 'posix-spawn', '~> 0.3.13', require: false
gem 'bcrypt', '~> 3.1.6'
gem 'multi_json', '~> 1.12.1'

@ -384,6 +384,7 @@ GEM
activesupport (> 2.2.1)
nokogiri (~> 1.8.1)
rubyzip (~> 1.2.1)
posix-spawn (0.3.13)
powerpack (0.1.1)
prawn (2.2.2)
pdf-core (~> 0.7.0)
@ -680,6 +681,7 @@ DEPENDENCIES
passenger (~> 5.3.3)
pg (~> 1.0.0)
plaintext (= 0.1.0)
posix-spawn (~> 0.3.13)
prawn (~> 2.2)
prawn-table (~> 0.2.2)
pry-byebug (~> 3.6.0)

@ -28,7 +28,7 @@
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'open3'
require 'posix-spawn'
module OpenProject::TextFormatting::Formats
module Markdown
@ -97,18 +97,24 @@ module OpenProject::TextFormatting::Formats
private
##
# Run pandoc through open3 and raise if an exception occurred
def run_pandoc!(args, **options)
output, stderr_str, status = Open3.capture3('pandoc', *args, **options)
raise stderr_str unless status.success?
# Run pandoc through posix-spawn and raise if an exception occurred
def run_pandoc!(command, stdin_data: nil, timeout: pandoc_timeout)
child = POSIX::Spawn::Child.new('pandoc', *command, input: stdin_data, timeout: timeout)
raise child.err unless child.status.success?
output
child.out
rescue POSIX::Spawn::TimeoutExceeded => e
raise Timeout::Error, "Timeout occurred while running pandoc: #{e.message}"
end
def read_usage_string
run_pandoc! %w[--help]
end
def pandoc_timeout
ENV.fetch('OPENPROJECT_PANDOC_TIMEOUT_SECONDS', 10).to_i
end
def read_output_formats
@output_formats ||= begin
begin

@ -117,7 +117,6 @@ module OpenProject::TextFormatting::Formats
# Iterate in batches to avoid plucking too much
with_original_values_in_batches(klass, attributes) do |orig_values|
markdowns_in_groups = bulk_convert_textile_with_fallback(orig_values, attributes)
new_values = new_values_for(attributes, orig_values, markdowns_in_groups)
next if new_values.empty?
@ -198,11 +197,18 @@ module OpenProject::TextFormatting::Formats
markdown = execute_pandoc_with_stdin! textile
cleanup_after_pandoc(markdown)
if markdown.empty?
markdown
else
cleanup_after_pandoc(markdown)
end
end
def execute_pandoc_with_stdin!(textile)
pandoc.execute! textile
rescue Timeout::Error => e
warn "Execution of pandoc failed: #{e}"
''
rescue StandardError => e
raise "Execution of pandoc failed: #{e}"
end

Loading…
Cancel
Save