<commit_before>require 'resqorn/config'
require 'resqorn/listener'

module Resqorn
  # The master process.
  # * Spawns a listener.
  # * Tracks all work. (IO pipe from listener.)
  # * Handles signals.
  class Master
    def initialize(options)
      @config_path = options.fetch(:config_path)
      @pidfile     = options.fetch(:pidfile) { nil }
      @running_workers = []
    end

    # Public: Starts the master process.
    def run
      write_pid
      write_procline
      install_signal_handlers
      start_listener
      handle_signals
    end

    def start_listener
      if @listener_pid
        log "Listener is already running!"
        return
      end
      @listener_started_at = Time.now
      if @listener_pid = fork
        # master
        log "Started listener #{@listener_pid}"
      else
        uninstall_signal_handlers
        # Load the config in the listener process so that, if it does a 'require' or something, it only pollutes the listener.
        config = Config.load_file(@config_path)
        Listener.new(:config => config, :running_workers => @running_workers).run
      end
    end

    def kill_listener(signal)
      if @listener_pid
        log "Killing listener #{@listener_pid} with #{signal}"
        Process.kill(signal.to_s, @listener_pid)
        wait_listener
      end
    end

    def wait_listener
      if @listener_pid
        pid, status = Process.waitpid2(@listener_pid)
        if status.exitstatus != 0
          log "Listener exited #{status}"
        end
        @listener_pid = nil
      end
    end

    SIGNALS = [ :HUP, :INT, :TERM, :QUIT, :CHLD ]

    SIGNAL_QUEUE = []
<commit_msg>Ensure that the listener process exits.<commit_after>require 'resqorn/config'
require 'resqorn/listener'

module Resqorn
  # The master process.
  # * Spawns a listener.
  # * Tracks all work. (IO pipe from listener.)
  # * Handles signals.
  class Master
    def initialize(options)
      @config_path = options.fetch(:config_path)
      @pidfile     = options.fetch(:pidfile) { nil }
      @running_workers = []
    end

    # Public: Starts the master process.
    def run
      write_pid
      write_procline
      install_signal_handlers
      start_listener
      handle_signals
    end

    def start_listener
      if @listener_pid
        log "Listener is already running!"
        return
      end
      @listener_started_at = Time.now
      if @listener_pid = fork
        # master
        log "Started listener #{@listener_pid}"
      else
        uninstall_signal_handlers
        # Load the config in the listener process so that, if it does a 'require' or something, it only pollutes the listener.
        config = Config.load_file(@config_path)
        Listener.new(:config => config, :running_workers => @running_workers).run
        exit
      end
    end

    def kill_listener(signal)
      if @listener_pid
        log "Killing listener #{@listener_pid} with #{signal}"
        Process.kill(signal.to_s, @listener_pid)
        wait_listener
      end
    end

    def wait_listener
      if @listener_pid
        pid, status = Process.waitpid2(@listener_pid)
        if status.exitstatus != 0
          log "Listener exited #{status}"
        end
        @listener_pid = nil
      end
    end

    SIGNALS = [ :HUP, :INT, :TERM, :QUIT, :CHLD ]

    SIGNAL_QUEUE = []

{'fraction_non_alphanumeric': 0.0812106682649086, 'fraction_numerical': 0.001198681450404555, 'mean_word_length': 2.3049504950495048, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1266849', 'n_tokens_mistral': 1003, 'n_tokens_neox': 976, 'n_words': 282}