Commit 9a373248 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Option to set the number of parallel processes.

Created wrapper around parallel gem that passes the same config
to each call of Parallel#map or Parallel#each, or disables
parallelization completely when in_processes => 0 specified.

Useful for debugging to get deterministic output.

It's also a step towards Windows support - parallel gem doesn't work
there.
parent e70d509c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -38,6 +38,13 @@ opts = OptionParser.new do | opts |
    app.export = :json
  end

  # For debugging it's often useful to set --processes=0 to get deterministic results.
  opts.on('-p', '--processes=COUNT', "The number of parallel processes to use.",
    "Defaults to the number of processors/cores.",
    "Set to 0 to disable parallel processing completely.") do |count|
    app.processes = count.to_i
  end

  opts.on('-v', '--verbose', "This will fill up your console.") do
    app.verbose = true
  end
+11 −4
Original line number Diff line number Diff line
@@ -10,9 +10,9 @@ require 'jsduck/relations'
require 'jsduck/page'
require 'jsduck/exporter'
require 'jsduck/timer'
require 'jsduck/parallel_wrap'
require 'json'
require 'fileutils'
require 'parallel'

module JsDuck

@@ -32,6 +32,13 @@ module JsDuck
      @verbose = false
      @export = nil
      @timer = Timer.new
      @parallel = ParallelWrap.new
    end

    # Sets the nr of parallel processes to use.
    # Set to 0 to disable parallelization completely.
    def processes=(count)
      @parallel = ParallelWrap.new(:in_processes => count)
    end

    # Call this after input parameters set
@@ -62,7 +69,7 @@ module JsDuck
    # Parses the files in parallel using as many processes as available CPU-s
    def parallel_parse(filenames)
      src = SourceFormatter.new(@output_dir + "/source", @export ? :format_pre : :format_page)
      Parallel.map(filenames) do |fname|
      @parallel.map(filenames) do |fname|
        puts "Parsing #{fname} ..." if @verbose
        code = IO.read(fname)
        {
@@ -123,7 +130,7 @@ module JsDuck
    # We do it in parallel using as many processes as available CPU-s
    def write_pages(path, relations)
      cache = {}
      Parallel.each(relations.classes) do |cls|
      @parallel.each(relations.classes) do |cls|
        filename = path + "/" + cls[:name] + ".html"
        puts "Writing to #{filename} ..." if @verbose
        html = Page.new(cls, relations, cache).to_html
@@ -134,7 +141,7 @@ module JsDuck
    # Writes JSON export file for each class
    def write_json(path, relations)
      exporter = Exporter.new(relations)
      Parallel.each(relations.classes) do |cls|
      @parallel.each(relations.classes) do |cls|
        filename = path + "/" + cls[:name] + ".json"
        puts "Writing to #{filename} ..." if @verbose
        hash = exporter.export(cls)
+31 −0
Original line number Diff line number Diff line
require 'parallel'

module JsDuck

  # Wrapper around the parallel gem that falls back to simple
  # Array#map and Array#each when :in_processes => 0 specified.
  class ParallelWrap

    # Takes config object for parallel
    def initialize(cfg = {})
      @cfg = cfg
    end

    def each(arr, &block)
      if @cfg[:in_processes] == 0
        arr.each &block
      else
        Parallel.each(arr, @cfg, &block)
      end
    end

    def map(arr, &block)
      if @cfg[:in_processes] == 0
        arr.map &block
      else
        Parallel.map(arr, @cfg, &block)
      end
    end
  end

end