# class Bundler::Worker

### Constants

POISON

### Attributes

name[R]

@return [String] the name of the worker

### Public Class Methods

new(size, name, func) click to toggle source

Creates a worker pool of specified size

@param size [Integer] Size of pool @param name [String] name the name of the worker @param func [Proc] job to run in inside the worker pool

    # File lib/bundler/worker.rb, line 22
    def initialize(size, name, func)
      @name = name
      @request_queue = Queue.new
      @response_queue = Queue.new
      @func = func
      @size = size
      @threads = nil
      SharedHelpers.trap("INT") { abort_threads }
    end

### Public Instance Methods

deq() click to toggle source

Retrieves results of job function being executed in worker pool

    # File lib/bundler/worker.rb, line 41
    def deq
      result = @response_queue.deq
      raise result.exception if result.is_a?(WrappedException)
      result
    end

enq(obj) click to toggle source

Enqueue a request to be executed in the worker pool

@param obj [String] mostly it is name of spec that should be downloaded

    # File lib/bundler/worker.rb, line 35
    def enq(obj)
      create_threads unless @threads
      @request_queue.enq obj
    end

stop() click to toggle source

    # File lib/bundler/worker.rb, line 47
    def stop
      stop_threads
    end

### Private Instance Methods

abort_threads() click to toggle source

    # File lib/bundler/worker.rb, line 76
    def abort_threads
      return unless @threads
      Bundler.ui.debug("\n#{caller.join("\n")}")
      @threads.each(&:exit)
      exit 1
    end

apply_func(obj, i) click to toggle source

    # File lib/bundler/worker.rb, line 61
    def apply_func(obj, i)
      @func.call(obj, i)
    rescue Exception => e # rubocop:disable Lint/RescueException
      WrappedException.new(e)
    end

create_threads() click to toggle source

    # File lib/bundler/worker.rb, line 83
    def create_threads
      creation_errors = []

      @threads = Array.new(@size) do |i|
        begin
          Thread.start { process_queue(i) }.tap do |thread|
            thread.name = "#{name} Worker ##{i}" if thread.respond_to?(:name=)
          end
        rescue ThreadError => e
          creation_errors << e
          nil
        end
      end.compact

      return if creation_errors.empty?

      message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}"
      raise ThreadCreationError, message if @threads.empty?
      Bundler.ui.info message
    end

process_queue(i) click to toggle source

    # File lib/bundler/worker.rb, line 53
    def process_queue(i)
      loop do
        obj = @request_queue.deq
        break if obj.equal? POISON
        @response_queue.enq apply_func(obj, i)
      end
    end

stop_threads() click to toggle source

Stop the worker threads by sending a poison object down the request queue so as worker threads after retrieving it, shut themselves down

    # File lib/bundler/worker.rb, line 69
    def stop_threads
      return unless @threads
      @threads.each { @request_queue.enq POISON }
      @threads.each(&:join)
      @threads = nil
    end