<commit_before>module WoodhouseRemoteUpdate::Sender

  class Updater
    attr_accessor :type
    attr_accessor :listener

    class NullUpdateListener
      def notify(job)
        # ;)
      end
    end

    def initialize(type, keyw = {})
      self.type = type
      self.listener ||= keyw[:listener] || NullUpdateListener
    end

    def update(data)
      send_update(type, data)
    end

    class Batched
      attr_accessor :updater

      def initialize(type, updater, keyw = {})
        self.updater = updater.send :new, type, keyw
      end

      def listener=(v)
        updater.listener = v
      end

      def in_batch
        @batch = []
        yield self
        updater.update(@batch) unless @batch.empty?
      ensure
        @batch = nil
      end

      def update(data)
        if @batch
          @batch << data
        else
          updater.update(data)
        end
      end

    end

    class << self
      attr_accessor :mutex

      def updater(type)
        type = type.to_sym
        updater = nil

        WoodhouseRemoteUpdate::Sender::Updater.mutex.synchronize do
          Thread.current[:hub_updaters] ||= {}
          updater = Thread.current[:hub_updaters][type] ||= Batched.new(type, self)
        end

        updater
      end

      def in_batch(type, &blk)
        updater(type).in_batch(&blk)
      end

      def update(type, data)
        updater(type).update(data)
      end

    end

    @mutex = Mutex.new<commit_msg>Allow batched updates to be manually canceled.<commit_after>module WoodhouseRemoteUpdate::Sender

  class Updater
    attr_accessor :type
    attr_accessor :listener

    class NullUpdateListener
      def notify(job)
        # ;)
      end
    end

    def initialize(type, keyw = {})
      self.type = type
      self.listener ||= keyw[:listener] || NullUpdateListener
    end

    def update(data)
      send_update(type, data)
    end

    class Batched
      attr_accessor :updater

      def initialize(type, updater, keyw = {})
        self.updater = updater.send :new, type, keyw
      end

      def listener=(v)
        updater.listener = v
      end
      
      def cancel!
        @canceled = true
      end

      def in_batch
        @batch = []
        yield self
        updater.update(@batch) unless empty? or canceled?
      ensure
        @batch = nil
      end

      def update(data)
        if @batch
          @batch << data
        else
          updater.update(data)
        end
      end
      
      def empty?
        @batch.nil? or @batch.empty?
      end
      
      def canceled?
        @canceled
      end

    end

    class << self
      attr_accessor :mutex

      def updater(type)
        type = type.to_sym
        updater = nil

        WoodhouseRemoteUpdate::Sender::Updater.mutex.synchronize do
          Thread.current[:hub_updaters] ||= {}
          updater = Thread.current[:hub_updaters][type] ||= Batched.new(type, self)
        end

        updater
      end

      def in_batch(type, &blk)
        updater(type).in_batch(&blk)
      end

      def update(type, data)
        updater(type).update(data)
      end

    end

    @mutex = Mutex.new
{'fraction_non_alphanumeric': 0.08783570300157978, 'fraction_numerical': 0.0, 'mean_word_length': 1.7482638888888888, 'pattern_counts': {'":': 0, '<': 11, '<?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': '2264648', 'n_tokens_mistral': 974, 'n_tokens_neox': 962, 'n_words': 228}