Commit b59388fb authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Turn ParallelWrap into singleton class.

Otherwise we need to pass around the ParallelWrap instance or config
for it, which is annoying.  Parallelization is more of an implementation
detail - passing it explicitly to every class that needs to make use
of it doesn't really fit to the interface of these classes.  We
shouldn't need to change the interface when switching from normal each
loop to parallel each.  So a singleton class it is.
parent d01dbb04
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ module JsDuck
      @opts = opts
      # Sets the nr of parallel processes to use.
      # Set to 0 to disable parallelization completely.
      @parallel = ParallelWrap.new(:in_processes => @opts.processes)
      ParallelWrap.in_processes = @opts.processes
      # Turn JSON pretty-printing on/off
      JsonDuck.pretty = @opts.pretty_json
    end
@@ -47,7 +47,7 @@ module JsDuck
      result = aggregate(parsed_files)
      @relations = filter_classes(result)
      InheritDoc.new(@relations).resolve_all
      Importer.import(@opts.imports, @relations, @parallel)
      Importer.import(@opts.imports, @relations)
      Lint.new(@relations).run

      # Initialize guides, videos, examples, ...
@@ -83,7 +83,7 @@ module JsDuck
        # between source files and classes. Therefore it MUST to be done
        # after writing sources which needs the links to work.
        if @opts.source
          source_writer = SourceWriter.new(parsed_files, @parallel)
          source_writer = SourceWriter.new(parsed_files)
          source_writer.write(@opts.output_dir + "/source")
        end
        format_classes
@@ -104,7 +104,7 @@ module JsDuck

    # Parses the files in parallel using as many processes as available CPU-s
    def parallel_parse(filenames)
      @parallel.map(filenames) do |fname|
      ParallelWrap.map(filenames) do |fname|
        Logger.instance.log("Parsing", fname)
        begin
          SourceFile.new(JsDuck::IO.read(fname), fname, @opts)
@@ -165,7 +165,7 @@ module JsDuck
      # Don't format types when exporting
      class_formatter.include_types = !@opts.export
      # Format all doc-objects in parallel
      formatted_classes = @parallel.map(@relations.classes) do |cls|
      formatted_classes = ParallelWrap.map(@relations.classes) do |cls|
        Logger.instance.log("Markdown formatting #{cls[:name]}")
        begin
          {
+2 −3
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ module JsDuck
    def initialize(exporter_class, relations, opts)
      @relations = relations
      @exporter = exporter_class.new(relations, opts)
      @parallel = ParallelWrap.new(:in_processes => opts.processes)
    end

    # Writes class data into given directory or STDOUT when dir == :stdout.
@@ -24,13 +23,13 @@ module JsDuck
    private

    def write_stdout
      json = @parallel.map(@relations.classes) {|cls| @exporter.export(cls) }.compact
      json = ParallelWrap.map(@relations.classes) {|cls| @exporter.export(cls) }.compact
      Stdout.instance.add(json)
    end

    def write_dir(dir, extension)
      FileUtils.mkdir(dir)
      @parallel.each(@relations.classes) do |cls|
      ParallelWrap.each(@relations.classes) do |cls|
        filename = dir + "/" + cls[:name] + extension
        Logger.instance.log("Writing docs", filename)
        json = @exporter.export(cls)
+2 −3
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ module JsDuck
    def initialize(exporter_class, guides, opts)
      @guides = guides
      @exporter = exporter_class.new(guides, opts)
      @parallel = ParallelWrap.new(:in_processes => opts.processes)
    end

    # Writes guide data into given directory or STDOUT when dir == :stdout.
@@ -24,13 +23,13 @@ module JsDuck
    private

    def write_stdout
      json = @parallel.map(all_guides) {|guide| @exporter.export_guide(guide) }.compact
      json = ParallelWrap.map(all_guides) {|guide| @exporter.export_guide(guide) }.compact
      Stdout.instance.add(json)
    end

    def write_dir(dir, extension)
      FileUtils.mkdir(dir) unless File.exists?(dir)
      @parallel.each(all_guides) do |guide|
      ParallelWrap.each(all_guides) do |guide|
        filename = dir + "/" + guide["name"] + extension
        Logger.instance.log("Writing guide", filename)
        json = @exporter.export_guide(guide)
+7 −6
Original line number Diff line number Diff line
require 'jsduck/json_duck'
require 'jsduck/null_object'
require 'jsduck/logger'
require 'jsduck/parallel_wrap'

module JsDuck

@@ -9,20 +10,20 @@ module JsDuck
    module_function

    # Loads in exported docs and generates @since and @new tags based on that data.
    def import(imports, relations, parallel)
    def import(imports, relations)
      if imports.length > 0
        generate_since_tags(read_all(imports, parallel), relations)
        generate_since_tags(read_all(imports), relations)
      end
    end

    # Reads in data for all versions, returning array of
    # version/class-data pairs.  We don't use a hash to preserve the
    # order of versions (from oldest to newest).
    def read_all(imports, parallel)
    def read_all(imports)
      imports.map do |ver|
        {
          :version => ver[:version],
          :classes => ver[:path] ? read(ver, parallel) : current_version,
          :classes => ver[:path] ? read(ver) : current_version,
        }
      end
    end
@@ -32,9 +33,9 @@ module JsDuck
    end

    # Reads in data from all .json files in directory
    def read(ver, parallel)
    def read(ver)
      # Map list of files into pairs of (classname, members-hash)
      pairs = parallel.map(Dir[ver[:path] + "/*.json"]) do |filename|
      pairs = ParallelWrap.map(Dir[ver[:path] + "/*.json"]) do |filename|
        JsDuck::Logger.instance.log("Importing #{ver[:version]}", filename)
        json = JsonDuck.read(filename)
        [json["name"],  members_id_index(json)]
+10 −9
Original line number Diff line number Diff line
@@ -5,25 +5,26 @@ module JsDuck
  # Wrapper around the parallel gem that falls back to simple
  # Array#map and Array#each when :in_processes => 0 specified.
  class ParallelWrap
    @@in_processes = nil

    # Takes config object for parallel
    def initialize(cfg = {})
      @cfg = cfg
    # Sets globally the nr of processes to use.
    def self.in_processes=(n)
      @@in_processes = n
    end

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

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