<commit_before>class TaskVault

  # This is meant to be an abstract class that all the various TaskVault components inherit from to get boilerplate code out of the way
  class Component
    attr_reader :message_queue, :parent, :thread, :started, :stopped, :message_handlers

    def initialize parent = nil, *args, **named
      self.parent = parent
      @message_handlers = [:default]
      setup_defaults
      process_args(*args, **named)
      if named.include?(:start)
        init_thread if named.delete(:start)
      end
    end

    def start
      init_thread unless running?
      @started = Time.now
      queue_msg("Starting #{self.class}", severity: 5)
      running?
    end

    def stop
      queue_msg("Stopping #{self.class}", severity: 5)
      @stopped = Time.now
      @thread.kill if @thread
      sleep(0.3) # Need to wait for shutdown of thread before running is called. This is a possible race condition.
      !running?
    end

    def restart
      queue_msg("Restarting #{self.class}", severity: 5)
      stop
      start
    end

    def uptime
      return 0 if @started.nil?
      running? ? Time.now - @started : 0
    end

    def running?
      defined?(@thread) && @thread.alive?
    end

    def message_handlers= handlers
      @message_handlers = [handlers].flatten
    end

    def queue_msg msg, **meta
      @message_queue = [] if !defined?(@message_queue)
      @message_queue.push({ msg:msg, handlers:@message_handlers, meta:meta.merge({time: Time.now, component: self.class.to_s}) })
    end
<commit_msg>Added check to ensure thread is not nil<commit_after>class TaskVault

  # This is meant to be an abstract class that all the various TaskVault components inherit from to get boilerplate code out of the way
  class Component
    attr_reader :message_queue, :parent, :thread, :started, :stopped, :message_handlers

    def initialize parent = nil, *args, **named
      self.parent = parent
      @message_handlers = [:default]
      setup_defaults
      process_args(*args, **named)
      if named.include?(:start)
        init_thread if named.delete(:start)
      end
    end

    def start
      init_thread unless running?
      @started = Time.now
      queue_msg("Starting #{self.class}", severity: 5)
      running?
    end

    def stop
      queue_msg("Stopping #{self.class}", severity: 5)
      @stopped = Time.now
      @thread.kill if @thread
      sleep(0.3) # Need to wait for shutdown of thread before running is called. This is a possible race condition.
      !running?
    end

    def restart
      queue_msg("Restarting #{self.class}", severity: 5)
      stop
      start
    end

    def uptime
      return 0 if @started.nil?
      running? ? Time.now - @started : 0
    end

    def running?
      defined?(@thread) && !@thread.nil? && @thread.alive?
    end

    def message_handlers= handlers
      @message_handlers = [handlers].flatten
    end

    def queue_msg msg, **meta
      @message_queue = [] if !defined?(@message_queue)
      @message_queue.push({ msg:msg, handlers:@message_handlers, meta:meta.merge({time: Time.now, component: self.class.to_s}) })
    end

{'fraction_non_alphanumeric': 0.09863188036907414, 'fraction_numerical': 0.004454342984409799, 'mean_word_length': 2.7384066587395957, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '895712', 'n_tokens_mistral': 977, 'n_tokens_neox': 920, 'n_words': 298}