elastics 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rspec +1 -0
 - data/.travis.yml +7 -0
 - data/README.md +80 -9
 - data/Rakefile +3 -8
 - data/elastics.gemspec +4 -1
 - data/lib/elastics.rb +11 -0
 - data/lib/elastics/active_record.rb +19 -4
 - data/lib/elastics/active_record/helper_methods.rb +27 -26
 - data/lib/elastics/active_record/instrumentation.rb +63 -7
 - data/lib/elastics/active_record/model_schema.rb +22 -17
 - data/lib/elastics/active_record/search_result.rb +49 -0
 - data/lib/elastics/active_record/tasks_config.rb +25 -0
 - data/lib/elastics/capistrano.rb +14 -0
 - data/lib/elastics/client.rb +49 -22
 - data/lib/elastics/client/cluster.rb +70 -0
 - data/lib/elastics/railtie.rb +5 -4
 - data/lib/elastics/tasks.rb +20 -19
 - data/lib/elastics/tasks/config.rb +38 -0
 - data/lib/elastics/tasks/indices.rb +72 -10
 - data/lib/elastics/tasks/mappings.rb +11 -5
 - data/lib/elastics/tasks/migrations.rb +42 -0
 - data/lib/elastics/version.rb +1 -1
 - data/lib/elastics/version_manager.rb +86 -0
 - data/lib/tasks/elastics.rake +31 -8
 - data/spec/lib/elastics/client/cluster_spec.rb +108 -0
 - data/spec/spec_helper.rb +9 -0
 - metadata +62 -7
 - data/lib/elastics/active_record/log_subscriber.rb +0 -27
 
| 
         @@ -7,11 +7,17 @@ module Elastics 
     | 
|
| 
       7 
7 
     | 
    
         
             
                    @mappings_paths ||= base_paths.map { |x| File.join x, 'mappings' }
         
     | 
| 
       8 
8 
     | 
    
         
             
                  end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
                  # Mappings to put can be filtered with `:indices` & `:types` arrays.
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def put_mappings(options = {})
         
     | 
| 
      
 12 
     | 
    
         
            +
                    version = options.fetch :version, :current
         
     | 
| 
      
 13 
     | 
    
         
            +
                    filter = options[:indices].try!(:map, &:to_s)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    each_filtered(types, options[:types]) do |type|
         
     | 
| 
       12 
15 
     | 
    
         
             
                      index = index_for_type(type)
         
     | 
| 
       13 
     | 
    
         
            -
                       
     | 
| 
       14 
     | 
    
         
            -
                       
     | 
| 
      
 16 
     | 
    
         
            +
                      next if filter && !filter.include?(index)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      versioned_index = versioned_index_name(index, version)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      log "Putting mapping #{index}/#{type} (#{versioned_index}/#{type})"
         
     | 
| 
      
 19 
     | 
    
         
            +
                      client.put_mapping index: versioned_index, type: type,
         
     | 
| 
      
 20 
     | 
    
         
            +
                        data: mappings[type]
         
     | 
| 
       15 
21 
     | 
    
         
             
                    end
         
     | 
| 
       16 
22 
     | 
    
         
             
                  end
         
     | 
| 
       17 
23 
     | 
    
         | 
| 
         @@ -33,7 +39,7 @@ module Elastics 
     | 
|
| 
       33 
39 
     | 
    
         
             
                  end
         
     | 
| 
       34 
40 
     | 
    
         | 
| 
       35 
41 
     | 
    
         
             
                  def index_for_type(type)
         
     | 
| 
       36 
     | 
    
         
            -
                    config[:index] ||  
     | 
| 
      
 42 
     | 
    
         
            +
                    config[:index] || type
         
     | 
| 
       37 
43 
     | 
    
         
             
                  end
         
     | 
| 
       38 
44 
     | 
    
         
             
                end
         
     | 
| 
       39 
45 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Elastics
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Tasks
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Migrations
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def migrate(options = {})
         
     | 
| 
      
 5 
     | 
    
         
            +
                    create_indices(options)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    put_mappings(options)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def migrate!(options = {})
         
     | 
| 
      
 10 
     | 
    
         
            +
                    options_next = options.merge version: :next
         
     | 
| 
      
 11 
     | 
    
         
            +
                    drop_indices(options_next)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    create_indices(options_next)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    put_mappings(options_next)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    reindex(options_next) if options.fetch(:reindex, true)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    forward_aliases(options)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def reindex(options = {})
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version = options.fetch(:version, :current)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    Rails.application.eager_load! if defined?(Rails)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    VersionManager.use_version version do
         
     | 
| 
      
 22 
     | 
    
         
            +
                      models_to_reindex(options).each do |model|
         
     | 
| 
      
 23 
     | 
    
         
            +
                        log "Reindexing #{model.elastics_index_base} into " \
         
     | 
| 
      
 24 
     | 
    
         
            +
                          "#{model.elastics_index_name}/#{model.elastics_type_name}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                        model.reindex_elastics
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def models_to_reindex(options = {})
         
     | 
| 
      
 31 
     | 
    
         
            +
                    indices = options[:indices].try!(:map, &:to_s)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    types = options[:types].try!(:map, &:to_s)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    models = Elastics.models.select do |model|
         
     | 
| 
      
 34 
     | 
    
         
            +
                      next if indices && !indices.include?(model.elastics_index_base)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      next if types && !types.include?(model.elastics_type_name)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      true
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    models.reject { |model| models.find { |other| model < other } }
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/elastics/version.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Elastics
         
     | 
| 
      
 2 
     | 
    
         
            +
              class VersionManager
         
     | 
| 
      
 3 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def default_version
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @default_version = ENV['ELASTICS_MAPPING_VERSION'] unless defined?(@default_version)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    @default_version
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def default_version=(version)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @default_version = version
         
     | 
| 
      
 11 
     | 
    
         
            +
                    Elastics.models.each &:reset_elastics_index_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def use_version(version)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    old_version = default_version
         
     | 
| 
      
 16 
     | 
    
         
            +
                    self.default_version = version
         
     | 
| 
      
 17 
     | 
    
         
            +
                    yield
         
     | 
| 
      
 18 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 19 
     | 
    
         
            +
                    self.default_version = old_version
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                attr_reader :service_index
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def initialize(client, options = {})
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @service_index = options[:service_index] || '.elastics'
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @index_prefix = options[:index_prefix]
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @client = client
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def reset
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @versions = nil
         
     | 
| 
      
 33 
     | 
    
         
            +
                  self
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def update(index, data)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  set index, versions[index].merge(data)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def set(index, data)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @client.post index: @service_index, type: :mapping_versions,
         
     | 
| 
      
 42 
     | 
    
         
            +
                    id: prefixed_index(index), data: data
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @versions[index] = data.with_indifferent_access
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def versions
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @versions ||= Hash.new do |hash, index|
         
     | 
| 
      
 48 
     | 
    
         
            +
                    result = @client.get index: @service_index, type: :mapping_versions,
         
     | 
| 
      
 49 
     | 
    
         
            +
                      id: prefixed_index(index)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    if result
         
     | 
| 
      
 51 
     | 
    
         
            +
                      hash[index] = result['_source'].with_indifferent_access
         
     | 
| 
      
 52 
     | 
    
         
            +
                    else
         
     | 
| 
      
 53 
     | 
    
         
            +
                      set index, current: 0
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def current_version(index)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  versions[index][:current]
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def next_version(index)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  current_version(index) + 1
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                def version_number(index, version)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  case version.to_s
         
     | 
| 
      
 68 
     | 
    
         
            +
                  when 'current'  then current_version(index)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  when 'next'     then next_version(index)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  else raise NameError, "Invalid version alias: #{version}"
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def prefixed_index(index)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  "#{@index_prefix}#{index}"
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def index_name(index, version = self.class.default_version)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  if version && version != :alias
         
     | 
| 
      
 80 
     | 
    
         
            +
                    "#{prefixed_index(index)}-v#{version_number index, version}"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  else
         
     | 
| 
      
 82 
     | 
    
         
            +
                    prefixed_index(index)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tasks/elastics.rake
    CHANGED
    
    | 
         @@ -1,20 +1,43 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            namespace 'elastics' do
         
     | 
| 
       2 
     | 
    
         
            -
              task load_config 
     | 
| 
      
 2 
     | 
    
         
            +
              task :load_config do |task, args|
         
     | 
| 
      
 3 
     | 
    
         
            +
                [:environment, 'db:load_config'].each do |dep|
         
     | 
| 
      
 4 
     | 
    
         
            +
                  Rake::Task[dep].invoke if Rake::Task.task_defined?(dep)
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
                @elastics_options = {
         
     | 
| 
      
 7 
     | 
    
         
            +
                  version:  ENV['version'] || :current,
         
     | 
| 
      
 8 
     | 
    
         
            +
                  reindex:  !ENV.key?('no_reindex'),
         
     | 
| 
      
 9 
     | 
    
         
            +
                  drop:     !ENV.key?('no_drop'),
         
     | 
| 
      
 10 
     | 
    
         
            +
                  types:    ENV['types'] && ENV['types'].split(',').map(&:strip),
         
     | 
| 
      
 11 
     | 
    
         
            +
                  indices:  args.extras.empty? ? nil : args.extras
         
     | 
| 
      
 12 
     | 
    
         
            +
                }
         
     | 
| 
       3 
13 
     | 
    
         
             
              end
         
     | 
| 
       4 
14 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
              desc ' 
     | 
| 
       6 
     | 
    
         
            -
              task  
     | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
       8 
     | 
    
         
            -
                Elastics::Tasks.migrate(flush: flush)
         
     | 
| 
      
 15 
     | 
    
         
            +
              desc 'Drop administrative index'
         
     | 
| 
      
 16 
     | 
    
         
            +
              task :purge, [:keep_data] => :load_config do |task, args|
         
     | 
| 
      
 17 
     | 
    
         
            +
                Elastics::Tasks.purge args[:keep_data]
         
     | 
| 
       9 
18 
     | 
    
         
             
              end
         
     | 
| 
       10 
19 
     | 
    
         | 
| 
       11 
20 
     | 
    
         
             
              desc 'Creates indices'
         
     | 
| 
       12 
21 
     | 
    
         
             
              task create: :load_config do
         
     | 
| 
       13 
     | 
    
         
            -
                Elastics::Tasks.create_indices
         
     | 
| 
      
 22 
     | 
    
         
            +
                Elastics::Tasks.create_indices @elastics_options
         
     | 
| 
       14 
23 
     | 
    
         
             
              end
         
     | 
| 
       15 
24 
     | 
    
         | 
| 
       16 
25 
     | 
    
         
             
              desc 'Drops indices'
         
     | 
| 
       17 
     | 
    
         
            -
              task  
     | 
| 
       18 
     | 
    
         
            -
                Elastics::Tasks. 
     | 
| 
      
 26 
     | 
    
         
            +
              task drop: :load_config do
         
     | 
| 
      
 27 
     | 
    
         
            +
                Elastics::Tasks.drop_indices @elastics_options
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              desc 'Creates indices and applies mappings. Full migration when param is present'
         
     | 
| 
      
 31 
     | 
    
         
            +
              task migrate: :load_config do
         
     | 
| 
      
 32 
     | 
    
         
            +
                if ENV['full']
         
     | 
| 
      
 33 
     | 
    
         
            +
                  Elastics::Tasks.migrate! @elastics_options
         
     | 
| 
      
 34 
     | 
    
         
            +
                else
         
     | 
| 
      
 35 
     | 
    
         
            +
                  Elastics::Tasks.migrate @elastics_options
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              desc 'Reindex'
         
     | 
| 
      
 40 
     | 
    
         
            +
              task reindex: :load_config do
         
     | 
| 
      
 41 
     | 
    
         
            +
                Elastics::Tasks.reindex @elastics_options
         
     | 
| 
       19 
42 
     | 
    
         
             
              end
         
     | 
| 
       20 
43 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,108 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Elastics::Client do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:client) { described_class.new(config) }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:config) { {
         
     | 
| 
      
 6 
     | 
    
         
            +
                host: hosts,
         
     | 
| 
      
 7 
     | 
    
         
            +
                resurrect_timeout: resurrect_timeout,
         
     | 
| 
      
 8 
     | 
    
         
            +
              } }
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:hosts) { [:one, :two, :three] }
         
     | 
| 
      
 10 
     | 
    
         
            +
              let(:resurrect_timeout) { 5 }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              describe '#next_cluster_host' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                subject { -> { client.send(:next_cluster_host) } }
         
     | 
| 
      
 14 
     | 
    
         
            +
                context 'when @hosts contains one element' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  let(:hosts) { [:one] }
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  it 'returns this host on each call' do
         
     | 
| 
      
 18 
     | 
    
         
            +
                    expect(6.times.map { subject.call }).to eq([:one] * 6)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                context 'when @hosts contains multiple elements' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  it 'returns host using round-robbin' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                    expect(6.times.map { subject.call }).to eq(hosts.cycle.take(6))
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  context 'and one host is dead' do
         
     | 
| 
      
 28 
     | 
    
         
            +
                    before { client.send(:add_dead_host, :one, resurrect_at) }
         
     | 
| 
      
 29 
     | 
    
         
            +
                    let(:resurrect_at) {}
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    it 'returns other hosts using round-robbin' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                      expect(6.times.map { subject.call }).to eq((hosts - [:one]).cycle.take(6))
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    context 'but should be resurrected' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                      let(:resurrect_at) { 0 }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      it 'resurrects this host' do
         
     | 
| 
      
 39 
     | 
    
         
            +
                        expect(6.times.map { subject.call }).to eq(hosts.cycle.take(7).drop(1))
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  context 'and all hosts are dead' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                    before { hosts.each { |host| client.send(:add_dead_host, host) } }
         
     | 
| 
      
 46 
     | 
    
         
            +
                    it { should raise_error(Elastics::Client::Cluster::NoAliveHosts) }
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              describe '#resurrect_cluster' do
         
     | 
| 
      
 52 
     | 
    
         
            +
                subject { -> { client.send(:resurrect_cluster) } }
         
     | 
| 
      
 53 
     | 
    
         
            +
                context 'when multiple hosts are blocked' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  before { hosts.each { |host| client.send(:add_dead_host, host) } }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  it { should_not change { client.instance_variable_get(:@hosts) }.from([]) }
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  context 'and can be resurrected' do
         
     | 
| 
      
 59 
     | 
    
         
            +
                    before { expect(Time).to receive(:now).and_return(resurrect_timeout.seconds.from_now) }
         
     | 
| 
      
 60 
     | 
    
         
            +
                    it { should change { client.instance_variable_get(:@hosts) }.from([]).to(hosts) }
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              describe '#http_request' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                subject { -> { client.send :http_request, :method, '/path', :query, :body } }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                context 'when all hosts are alive' do
         
     | 
| 
      
 69 
     | 
    
         
            +
                  it 'uses hosts using round-robbin' do
         
     | 
| 
      
 70 
     | 
    
         
            +
                    hosts.cycle.take(6).each do |host|
         
     | 
| 
      
 71 
     | 
    
         
            +
                      expect(client.client).to receive(:request).
         
     | 
| 
      
 72 
     | 
    
         
            +
                        with(:method, "http://#{host}/path", :query, :body, Elastics::Client::HEADERS)
         
     | 
| 
      
 73 
     | 
    
         
            +
                      subject.call
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                context 'when one host is unreachable' do
         
     | 
| 
      
 79 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 80 
     | 
    
         
            +
                    expect(client.client).to receive(:request).
         
     | 
| 
      
 81 
     | 
    
         
            +
                      with(:method, "http://one/path", :query, :body, Elastics::Client::HEADERS) do
         
     | 
| 
      
 82 
     | 
    
         
            +
                      raise Timeout::Error
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  it 'uses hosts using round-robbin' do
         
     | 
| 
      
 87 
     | 
    
         
            +
                    (hosts - [:one]).cycle.take(6).each do |host|
         
     | 
| 
      
 88 
     | 
    
         
            +
                      expect(client.client).to receive(:request).
         
     | 
| 
      
 89 
     | 
    
         
            +
                        with(:method, "http://#{host}/path", :query, :body, Elastics::Client::HEADERS)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
                    6.times { subject.call }
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                context 'when all hosts are unreachable' do
         
     | 
| 
      
 96 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 97 
     | 
    
         
            +
                    hosts.each do |host|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      expect(client.client).to receive(:request).
         
     | 
| 
      
 99 
     | 
    
         
            +
                        with(:method, "http://#{host}/path", :query, :body, Elastics::Client::HEADERS) do
         
     | 
| 
      
 100 
     | 
    
         
            +
                        raise Timeout::Error
         
     | 
| 
      
 101 
     | 
    
         
            +
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  it { should raise_error(Elastics::Client::Cluster::NoAliveHosts) }
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: elastics
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Max Melentiev
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2014- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2014-11-01 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: httpclient
         
     | 
| 
         @@ -44,14 +44,56 @@ dependencies: 
     | 
|
| 
       44 
44 
     | 
    
         
             
                requirements:
         
     | 
| 
       45 
45 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       46 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       47 
     | 
    
         
            -
                    version: '10'
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
       48 
48 
     | 
    
         
             
              type: :development
         
     | 
| 
       49 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       50 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       51 
51 
     | 
    
         
             
                requirements:
         
     | 
| 
       52 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       53 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       54 
     | 
    
         
            -
                    version: '10'
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: 3.1.0
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: 3.1.0
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: thread_safe
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: 0.3.4
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: 0.3.4
         
     | 
| 
      
 83 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 84 
     | 
    
         
            +
              name: activesupport
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 86 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 87 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 88 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 89 
     | 
    
         
            +
                    version: 4.1.6
         
     | 
| 
      
 90 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 91 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 92 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 93 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 96 
     | 
    
         
            +
                    version: 4.1.6
         
     | 
| 
       55 
97 
     | 
    
         
             
            description: Lightweight and extensible elasticsearch client
         
     | 
| 
       56 
98 
     | 
    
         
             
            email:
         
     | 
| 
       57 
99 
     | 
    
         
             
            - melentievm@gmail.com
         
     | 
| 
         @@ -60,6 +102,8 @@ extensions: [] 
     | 
|
| 
       60 
102 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       61 
103 
     | 
    
         
             
            files:
         
     | 
| 
       62 
104 
     | 
    
         
             
            - ".gitignore"
         
     | 
| 
      
 105 
     | 
    
         
            +
            - ".rspec"
         
     | 
| 
      
 106 
     | 
    
         
            +
            - ".travis.yml"
         
     | 
| 
       63 
107 
     | 
    
         
             
            - Gemfile
         
     | 
| 
       64 
108 
     | 
    
         
             
            - README.md
         
     | 
| 
       65 
109 
     | 
    
         
             
            - Rakefile
         
     | 
| 
         @@ -68,16 +112,24 @@ files: 
     | 
|
| 
       68 
112 
     | 
    
         
             
            - lib/elastics/active_record.rb
         
     | 
| 
       69 
113 
     | 
    
         
             
            - lib/elastics/active_record/helper_methods.rb
         
     | 
| 
       70 
114 
     | 
    
         
             
            - lib/elastics/active_record/instrumentation.rb
         
     | 
| 
       71 
     | 
    
         
            -
            - lib/elastics/active_record/log_subscriber.rb
         
     | 
| 
       72 
115 
     | 
    
         
             
            - lib/elastics/active_record/model_schema.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - lib/elastics/active_record/search_result.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - lib/elastics/active_record/tasks_config.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - lib/elastics/capistrano.rb
         
     | 
| 
       73 
119 
     | 
    
         
             
            - lib/elastics/client.rb
         
     | 
| 
      
 120 
     | 
    
         
            +
            - lib/elastics/client/cluster.rb
         
     | 
| 
       74 
121 
     | 
    
         
             
            - lib/elastics/query_helper.rb
         
     | 
| 
       75 
122 
     | 
    
         
             
            - lib/elastics/railtie.rb
         
     | 
| 
       76 
123 
     | 
    
         
             
            - lib/elastics/tasks.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - lib/elastics/tasks/config.rb
         
     | 
| 
       77 
125 
     | 
    
         
             
            - lib/elastics/tasks/indices.rb
         
     | 
| 
       78 
126 
     | 
    
         
             
            - lib/elastics/tasks/mappings.rb
         
     | 
| 
      
 127 
     | 
    
         
            +
            - lib/elastics/tasks/migrations.rb
         
     | 
| 
       79 
128 
     | 
    
         
             
            - lib/elastics/version.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - lib/elastics/version_manager.rb
         
     | 
| 
       80 
130 
     | 
    
         
             
            - lib/tasks/elastics.rake
         
     | 
| 
      
 131 
     | 
    
         
            +
            - spec/lib/elastics/client/cluster_spec.rb
         
     | 
| 
      
 132 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
       81 
133 
     | 
    
         
             
            homepage: http://github.com/printercu/elastics-rb
         
     | 
| 
       82 
134 
     | 
    
         
             
            licenses:
         
     | 
| 
       83 
135 
     | 
    
         
             
            - MIT
         
     | 
| 
         @@ -98,8 +150,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       98 
150 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       99 
151 
     | 
    
         
             
            requirements: []
         
     | 
| 
       100 
152 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       101 
     | 
    
         
            -
            rubygems_version: 2. 
     | 
| 
      
 153 
     | 
    
         
            +
            rubygems_version: 2.4.2
         
     | 
| 
       102 
154 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       103 
155 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       104 
156 
     | 
    
         
             
            summary: ElasticSearch client with ActiveRecord integration
         
     | 
| 
       105 
     | 
    
         
            -
            test_files: 
     | 
| 
      
 157 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 158 
     | 
    
         
            +
            - spec/lib/elastics/client/cluster_spec.rb
         
     | 
| 
      
 159 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 160 
     | 
    
         
            +
            has_rdoc: 
         
     |