<commit_before>require 'socket'
require 'fcntl'

require 'rubygems'
require 'active_support'
require 'json'

module Officer

  class GenericError < RuntimeError; end
  class AlreadyConnectedError < GenericError; end
  class LockError < GenericError; end
  class LockTimeoutError < LockError; end
  class UnlockError < GenericError; end

  class Client
    def initialize options={}
      options.reverse_merge! :host => 'localhost', :port => 11500

      @host = options[:host]
      @port = options[:port]

      connect
    end

    def reconnect
      disconnect
      connect
    end

    def lock name, options={}
      execute({:command => 'lock', :name => name, :timeout => options[:timeout]}.to_json)
    end

    def unlock name
      execute({:command => 'unlock', :name => name}.to_json)
    end

    def with_lock name, options={}
      response = lock name, options
      result = response['result']
      
      raise LockTimeoutError if result == 'timed_out'
      raise LockError unless %w(acquired already_acquired).include?(result)

      begin
        yield
      ensure
        # Deal with nested with_lock calls.  Only the outer most call should tell the server to unlock.
        if result == 'acquired'
          response = unlock name
          raise UnlockError unless response['result'] == 'released'
        end
      end
    end

    def reset
      execute({:command => 'reset'}.to_json)
    end

  private
    def connect
      raise AlreadyConnectedError if @socket

      @socket = TCPSocket.new @host, @port.to_i
      @socket.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
    end

    def disconnect
      @socket.close
      @socket = nil
    end

    def execute command
      @socket.write command + "\n"
      result = @socket.gets "\n"
      JSON.parse result.chomp
    rescue
      reconnect and raise
    end
  end

end<commit_msg>Minor fix<commit_after>require 'socket'
require 'fcntl'

require 'rubygems'
require 'active_support'
require 'json'

module Officer

  class GenericError < RuntimeError; end
  class AlreadyConnectedError < GenericError; end
  class LockError < GenericError; end
  class LockTimeoutError < LockError; end
  class UnlockError < GenericError; end

  class Client
    def initialize options={}
      options.reverse_merge! :host => 'localhost', :port => 11500

      @host = options[:host]
      @port = options[:port]

      connect
    end

    def reconnect
      disconnect
      connect
    end

    def lock name, options={}
      execute({:command => 'lock', :name => name, :timeout => options[:timeout]}.to_json)
    end

    def unlock name
      execute({:command => 'unlock', :name => name}.to_json)
    end

    def with_lock name, options={}
      response = lock name, options
      result = response['result']
      
      raise LockTimeoutError if result == 'timed_out'
      raise LockError unless %w(acquired already_acquired).include?(result)

      begin
        yield
      ensure
        # Deal with nested with_lock calls.  Only the outer most call should tell the server to unlock.
        if result == 'acquired'
          response = unlock name
          raise UnlockError unless response['result'] == 'released'
        end
      end
    end

    def reset
      execute({:command => 'reset'}.to_json)
    end

  private
    def connect
      raise AlreadyConnectedError if @socket

      @socket = TCPSocket.new @host, @port.to_i
      @socket.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
    end

    def disconnect
      @socket.close
      @socket = nil
    end

    def execute command
      @socket.write command + "\n"
      result = @socket.gets "\n"
      JSON.parse result.chomp
    rescue
      reconnect
      raise
    end
  end

end
{'fraction_non_alphanumeric': 0.08954423592493298, 'fraction_numerical': 0.002680965147453083, 'mean_word_length': 2.4967197750702907, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, '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': '730569', 'n_tokens_mistral': 1106, 'n_tokens_neox': 1063, 'n_words': 337}