ts-sidekiq-delta 0.1.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 +7 -0
 - data/.gitignore +16 -0
 - data/.rspec +1 -0
 - data/Gemfile +10 -0
 - data/Guardfile +17 -0
 - data/LICENSE +20 -0
 - data/README.markdown +36 -0
 - data/Rakefile +16 -0
 - data/config/redis-cucumber.conf +13 -0
 - data/cucumber.yml +2 -0
 - data/features/sidekiq_deltas.feature +62 -0
 - data/features/smart_indexing.feature +43 -0
 - data/features/step_definitions/common_steps.rb +76 -0
 - data/features/step_definitions/sidekiq_delta_steps.rb +33 -0
 - data/features/step_definitions/smart_indexing_steps.rb +3 -0
 - data/features/support/env.rb +31 -0
 - data/features/thinking_sphinx/database.example.yml +3 -0
 - data/features/thinking_sphinx/db/migrations/create_delayed_betas.rb +4 -0
 - data/features/thinking_sphinx/models/delayed_beta.rb +6 -0
 - data/lib/thinking_sphinx/deltas/sidekiq_delta.rb +64 -0
 - data/lib/thinking_sphinx/deltas/sidekiq_delta/delta_job.rb +51 -0
 - data/lib/thinking_sphinx/deltas/sidekiq_delta/flag_as_deleted_job.rb +20 -0
 - data/lib/thinking_sphinx/deltas/sidekiq_delta/railtie.rb +5 -0
 - data/lib/thinking_sphinx/deltas/sidekiq_delta/tasks.rb +38 -0
 - data/lib/ts-sidekiq-delta.rb +2 -0
 - data/spec/acceptance/sidekiq_deltas_spec.rb +50 -0
 - data/spec/acceptance/spec_helper.rb +5 -0
 - data/spec/acceptance/support/database_cleaner.rb +11 -0
 - data/spec/acceptance/support/sphinx_controller.rb +39 -0
 - data/spec/acceptance/support/sphinx_helpers.rb +39 -0
 - data/spec/internal/.gitignore +2 -0
 - data/spec/internal/app/indices/book_index.rb +3 -0
 - data/spec/internal/app/models/book.rb +3 -0
 - data/spec/internal/config/database.yml +5 -0
 - data/spec/internal/db/schema.rb +24 -0
 - data/spec/internal/log/.gitignore +1 -0
 - data/spec/spec_helper.rb +17 -0
 - data/tasks/rails.rake +1 -0
 - data/ts-sidekiq-delta.gemspec +26 -0
 - metadata +204 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 69d263abd6456994f89536fed3e8ab516e91d029
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: d8068a4e447382b7b8c95f08702ba8b7988a13f3
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 7ad79d13705125cdbbc5b7d171c7de7a3de5411189e36845adf9b5db7a4c9a9187c8eb0d91fcf32db56d6e5df377a8762541def04441c43b4c4f490a916653d5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 31e37ee5b4ae26931e4b0d18eeb275a5ea251c4dac16e6ee9deaebc0332250e3e73fa79431f4a1e254010c44e659341e7c6a8fb5e8341c3db3b9610e624aa5fe
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --color
         
     | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Guardfile
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            guard 'bundler' do
         
     | 
| 
      
 2 
     | 
    
         
            +
              watch('Gemfile')
         
     | 
| 
      
 3 
     | 
    
         
            +
              watch(/^.+\.gemspec/)
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            guard 'rspec', :version => 2, :cli => "-c --format progress", :all_on_start => false do
         
     | 
| 
      
 7 
     | 
    
         
            +
              watch(%r{^spec/.+_spec\.rb$})
         
     | 
| 
      
 8 
     | 
    
         
            +
              watch(%r{^lib/(.+)\.rb$})     { |m| "spec/#{m[1]}_spec.rb" }
         
     | 
| 
      
 9 
     | 
    
         
            +
              watch('spec/spec_helper.rb')  { "spec" }
         
     | 
| 
      
 10 
     | 
    
         
            +
            end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            guard 'cucumber', :all_on_start => false do
         
     | 
| 
      
 13 
     | 
    
         
            +
              watch(%r{^features/.+\.feature$})
         
     | 
| 
      
 14 
     | 
    
         
            +
              watch(%r{^features/support/.+$})          { 'features' }
         
     | 
| 
      
 15 
     | 
    
         
            +
              watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2009 Pat Allan
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.markdown
    ADDED
    
    | 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Delayed Deltas for Thinking Sphinx with Sidekiq
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            This code was heavily based on Aaron Gibralter's [ts-resque-delta](https://github.com/agibralter/ts-resque-delta), and was initially adapted for Sidekiq by [Danny Hawkins](https://github.com/danhawkins). This release is maintained by [Pat Allan](https://github.com/pat).
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This version of `ts-sidekiq-delta` works only with [Thinking Sphinx](https://github.com/pat/thinking-sphinx) v3 or newer. v1/v2 releases are not supported, and almost certainly will never be. It does work with the Flying Sphinx service, provided you're using 1.0.0 or newer of the `flying-sphinx` gem.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Get it into your Gemfile - and don't forget the version constraint!
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                gem 'ts-sidekiq-delta', '~> 0.1.0'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            In your index definitions, you'll want to include the delta setting as an initial option:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                ThinkingSphinx::Index.define(:article,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :with  => :active_record,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :delta => ThinkingSphinx::Deltas::SidekiqDelta
         
     | 
| 
      
 20 
     | 
    
         
            +
                ) do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # fields and attributes and such
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            If you've never used delta indexes before, you'll want to add the boolean
         
     | 
| 
      
 25 
     | 
    
         
            +
            column named `:delta` to each model's table and a corresponding database index:
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def change
         
     | 
| 
      
 28 
     | 
    
         
            +
                  add_column :articles, :delta, :boolean, :default => true, :null => false
         
     | 
| 
      
 29 
     | 
    
         
            +
                  add_index  :articles, :delta
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            From here on in, just use Thinking Sphinx and Sidekiq as you normally would, and you'll find your Sphinx indices are updated quite promptly by Sidekiq.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ## Licence
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Copyright (c) 2013, ts-sidekiq-delta was originally developed by Danny Hawkins, is currently maintained by Pat Allan, and is released under the open MIT Licence.
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rake
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'cucumber'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'cucumber/rake/task'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec) do |t|
         
     | 
| 
      
 8 
     | 
    
         
            +
              t.rspec_opts = ["-c", "--format progress"]
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Cucumber::Rake::Task.new(:features) do |t|
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            task :all_tests => [:spec, :features]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            task :default => :all_tests
         
     | 
    
        data/cucumber.yml
    ADDED
    
    
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Feature: Resque Delta Indexing
         
     | 
| 
      
 2 
     | 
    
         
            +
              In order to have delta indexing on frequently-updated sites
         
     | 
| 
      
 3 
     | 
    
         
            +
              Developers
         
     | 
| 
      
 4 
     | 
    
         
            +
              Should be able to use Resque to handle delta indices to lower system load
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              Background:
         
     | 
| 
      
 7 
     | 
    
         
            +
                Given Sphinx is running
         
     | 
| 
      
 8 
     | 
    
         
            +
                And I am searching on delayed betas
         
     | 
| 
      
 9 
     | 
    
         
            +
                And I have data and it has been indexed
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              Scenario: Delta Index should not fire automatically
         
     | 
| 
      
 12 
     | 
    
         
            +
                When I search for one
         
     | 
| 
      
 13 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                When I change the name of delayed beta one to eleven
         
     | 
| 
      
 16 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 17 
     | 
    
         
            +
                And I search for one
         
     | 
| 
      
 18 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                When I search for eleven
         
     | 
| 
      
 21 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              Scenario: Delta Index should fire when jobs are run
         
     | 
| 
      
 24 
     | 
    
         
            +
                When I search for one
         
     | 
| 
      
 25 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                When I change the name of delayed beta two to twelve
         
     | 
| 
      
 28 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 29 
     | 
    
         
            +
                And I search for twelve
         
     | 
| 
      
 30 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                When I run the delayed jobs
         
     | 
| 
      
 33 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 34 
     | 
    
         
            +
                And I search for twelve
         
     | 
| 
      
 35 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                When I search for two
         
     | 
| 
      
 38 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              Scenario: ensuring that duplicate jobs are deleted
         
     | 
| 
      
 41 
     | 
    
         
            +
                When I change the name of delayed beta two to fifty
         
     | 
| 
      
 42 
     | 
    
         
            +
                And I change the name of delayed beta five to twelve
         
     | 
| 
      
 43 
     | 
    
         
            +
                And I change the name of delayed beta one to fifteen
         
     | 
| 
      
 44 
     | 
    
         
            +
                And I change the name of delayed beta six to twenty
         
     | 
| 
      
 45 
     | 
    
         
            +
                And I run one delayed job
         
     | 
| 
      
 46 
     | 
    
         
            +
                Then there should be no more DeltaJobs on the Resque queue
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                When I run the delayed jobs
         
     | 
| 
      
 49 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 50 
     | 
    
         
            +
                And I search for fifty
         
     | 
| 
      
 51 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                When I search for two
         
     | 
| 
      
 54 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              Scenario: canceling jobs
         
     | 
| 
      
 57 
     | 
    
         
            +
                When I change the name of delayed beta two to fifty
         
     | 
| 
      
 58 
     | 
    
         
            +
                And I cancel the jobs
         
     | 
| 
      
 59 
     | 
    
         
            +
                And I run the delayed jobs
         
     | 
| 
      
 60 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 61 
     | 
    
         
            +
                And I search for fifty
         
     | 
| 
      
 62 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Feature: Smart Indexing
         
     | 
| 
      
 2 
     | 
    
         
            +
              In order to have core indexing that works well with resque delta indexing
         
     | 
| 
      
 3 
     | 
    
         
            +
              Developers
         
     | 
| 
      
 4 
     | 
    
         
            +
              Should be able to use smart index to update core indices
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              Background:
         
     | 
| 
      
 7 
     | 
    
         
            +
                Given Sphinx is running
         
     | 
| 
      
 8 
     | 
    
         
            +
                And I am searching on delayed betas
         
     | 
| 
      
 9 
     | 
    
         
            +
                And I have data
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              Scenario: Smart indexing should update core indices
         
     | 
| 
      
 12 
     | 
    
         
            +
                When I run the smart indexer
         
     | 
| 
      
 13 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 14 
     | 
    
         
            +
                And I search for one
         
     | 
| 
      
 15 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              Scenario: Smart indexing should reset the delta index
         
     | 
| 
      
 18 
     | 
    
         
            +
                Given I have indexed
         
     | 
| 
      
 19 
     | 
    
         
            +
                When I change the name of delayed beta one to eleven
         
     | 
| 
      
 20 
     | 
    
         
            +
                And I run the delayed jobs
         
     | 
| 
      
 21 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                When I change the name of delayed beta eleven to one
         
     | 
| 
      
 24 
     | 
    
         
            +
                And I run the smart indexer
         
     | 
| 
      
 25 
     | 
    
         
            +
                And I run the delayed jobs
         
     | 
| 
      
 26 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                When I search for eleven
         
     | 
| 
      
 29 
     | 
    
         
            +
                Then I should get 0 results
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              Scenario: Delta Index running after smart indexing should not hide records
         
     | 
| 
      
 32 
     | 
    
         
            +
                When I run the smart indexer
         
     | 
| 
      
 33 
     | 
    
         
            +
                And I run the delayed jobs
         
     | 
| 
      
 34 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                When I search for two
         
     | 
| 
      
 37 
     | 
    
         
            +
                Then I should get 1 result
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              Scenario: Smart index should remove existing delta jobs
         
     | 
| 
      
 40 
     | 
    
         
            +
                When I run the smart indexer
         
     | 
| 
      
 41 
     | 
    
         
            +
                And I run one delayed job
         
     | 
| 
      
 42 
     | 
    
         
            +
                And I wait for Sphinx to catch up
         
     | 
| 
      
 43 
     | 
    
         
            +
                Then there should be no more DeltaJobs on the Resque queue
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Before do
         
     | 
| 
      
 2 
     | 
    
         
            +
              $queries_executed = []
         
     | 
| 
      
 3 
     | 
    
         
            +
              ThinkingSphinx::Deltas::SidekiqDelta.clear!
         
     | 
| 
      
 4 
     | 
    
         
            +
              @model      = nil
         
     | 
| 
      
 5 
     | 
    
         
            +
              @method     = :search
         
     | 
| 
      
 6 
     | 
    
         
            +
              @query      = ""
         
     | 
| 
      
 7 
     | 
    
         
            +
              @conditions = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
              @with       = {}
         
     | 
| 
      
 9 
     | 
    
         
            +
              @without    = {}
         
     | 
| 
      
 10 
     | 
    
         
            +
              @with_all   = {}
         
     | 
| 
      
 11 
     | 
    
         
            +
              @options    = {}
         
     | 
| 
      
 12 
     | 
    
         
            +
              @results    = nil
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Given "Sphinx is running" do
         
     | 
| 
      
 16 
     | 
    
         
            +
              ThinkingSphinx::Configuration.instance.controller.should be_running
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Given /^I am searching on (.+)$/ do |model|
         
     | 
| 
      
 20 
     | 
    
         
            +
              @model = model.gsub(/\s/, '_').singularize.camelize.constantize
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            Given "I have data" do
         
     | 
| 
      
 24 
     | 
    
         
            +
              DelayedBeta.create(:name => "one")
         
     | 
| 
      
 25 
     | 
    
         
            +
              DelayedBeta.create(:name => "two")
         
     | 
| 
      
 26 
     | 
    
         
            +
              DelayedBeta.create(:name => "three")
         
     | 
| 
      
 27 
     | 
    
         
            +
              DelayedBeta.create(:name => "four")
         
     | 
| 
      
 28 
     | 
    
         
            +
              DelayedBeta.create(:name => "five")
         
     | 
| 
      
 29 
     | 
    
         
            +
              DelayedBeta.create(:name => "six")
         
     | 
| 
      
 30 
     | 
    
         
            +
              DelayedBeta.create(:name => "seven")
         
     | 
| 
      
 31 
     | 
    
         
            +
              DelayedBeta.create(:name => "eight")
         
     | 
| 
      
 32 
     | 
    
         
            +
              DelayedBeta.create(:name => "nine")
         
     | 
| 
      
 33 
     | 
    
         
            +
              DelayedBeta.create(:name => "ten")
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Given "I have indexed" do
         
     | 
| 
      
 37 
     | 
    
         
            +
              ThinkingSphinx::Deltas::SidekiqDelta.clear!
         
     | 
| 
      
 38 
     | 
    
         
            +
              ThinkingSphinx::Configuration.instance.controller.index
         
     | 
| 
      
 39 
     | 
    
         
            +
              sleep(1.5)
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            Given "I have data and it has been indexed" do
         
     | 
| 
      
 43 
     | 
    
         
            +
              step "I have data"
         
     | 
| 
      
 44 
     | 
    
         
            +
              step "I have indexed"
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            When "I wait for Sphinx to catch up" do
         
     | 
| 
      
 48 
     | 
    
         
            +
              sleep(0.5)
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            When /^I search for (\w+)$/ do |query|
         
     | 
| 
      
 52 
     | 
    
         
            +
              @results = nil
         
     | 
| 
      
 53 
     | 
    
         
            +
              @query = query
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            Then /^I should get (\d+) results?$/ do |count|
         
     | 
| 
      
 57 
     | 
    
         
            +
              results.length.should == count.to_i
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            Then /^I debug$/ do
         
     | 
| 
      
 61 
     | 
    
         
            +
              debugger
         
     | 
| 
      
 62 
     | 
    
         
            +
              0
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            def results
         
     | 
| 
      
 66 
     | 
    
         
            +
              @results ||= (@model || ThinkingSphinx).send(
         
     | 
| 
      
 67 
     | 
    
         
            +
                @method,
         
     | 
| 
      
 68 
     | 
    
         
            +
                @query,
         
     | 
| 
      
 69 
     | 
    
         
            +
                @options.merge(
         
     | 
| 
      
 70 
     | 
    
         
            +
                  :conditions => @conditions,
         
     | 
| 
      
 71 
     | 
    
         
            +
                  :with       => @with,
         
     | 
| 
      
 72 
     | 
    
         
            +
                  :without    => @without,
         
     | 
| 
      
 73 
     | 
    
         
            +
                  :with_all   => @with_all
         
     | 
| 
      
 74 
     | 
    
         
            +
                )
         
     | 
| 
      
 75 
     | 
    
         
            +
              )
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            When /^I run the delayed jobs$/ do
         
     | 
| 
      
 2 
     | 
    
         
            +
              unless @resque_worker
         
     | 
| 
      
 3 
     | 
    
         
            +
                @resque_worker = Resque::Worker.new("ts_delta")
         
     | 
| 
      
 4 
     | 
    
         
            +
                @resque_worker.register_worker
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
              while job = @resque_worker.reserve
         
     | 
| 
      
 7 
     | 
    
         
            +
                @resque_worker.perform(job)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            When /^I run one delayed job$/ do
         
     | 
| 
      
 12 
     | 
    
         
            +
              unless @resque_worker
         
     | 
| 
      
 13 
     | 
    
         
            +
                @resque_worker = Resque::Worker.new("ts_delta")
         
     | 
| 
      
 14 
     | 
    
         
            +
                @resque_worker.register_worker
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              job = @resque_worker.reserve
         
     | 
| 
      
 17 
     | 
    
         
            +
              @resque_worker.perform(job)
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            When /^I cancel the jobs$/ do
         
     | 
| 
      
 21 
     | 
    
         
            +
              ThinkingSphinx::Deltas::SidekiqDelta.clear!
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            When /^I change the name of delayed beta (\w+) to (\w+)$/ do |current, replacement|
         
     | 
| 
      
 25 
     | 
    
         
            +
              DelayedBeta.find_by_name(current).update_attributes(:name => replacement)
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            Then /^there should be no more DeltaJobs on the Resque queue$/ do
         
     | 
| 
      
 29 
     | 
    
         
            +
              job_classes = Resque.redis.lrange("queue:ts_delta", 0, -1).collect do |j|
         
     | 
| 
      
 30 
     | 
    
         
            +
                Resque.decode(j)["class"]
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              job_classes.should_not include("ThinkingSphinx::Deltas::SidekiqDelta::DeltaJob")
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'cucumber'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec/expectations'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'mock_redis'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            $:.unshift(File.join(PROJECT_ROOT, 'lib'))
         
     | 
| 
      
 10 
     | 
    
         
            +
            $:.unshift(File.dirname(__FILE__))
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            require 'cucumber/thinking_sphinx/internal_world'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            ActiveRecord::Base.default_timezone = :utc
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            world = Cucumber::ThinkingSphinx::InternalWorld.new
         
     | 
| 
      
 17 
     | 
    
         
            +
            world.configure_database
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require 'thinking_sphinx'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require 'thinking_sphinx/deltas/resque_delta'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            world.setup
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            Resque.redis = MockRedis.new
         
     | 
| 
      
 25 
     | 
    
         
            +
            Before do
         
     | 
| 
      
 26 
     | 
    
         
            +
              Sidekiq.redis{|r| r.flushall}
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            require 'database_cleaner'
         
     | 
| 
      
 30 
     | 
    
         
            +
            require 'database_cleaner/cucumber'
         
     | 
| 
      
 31 
     | 
    
         
            +
            DatabaseCleaner.strategy = :truncation
         
     | 
| 
         @@ -0,0 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sidekiq'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'thinking_sphinx'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class ThinkingSphinx::Deltas::SidekiqDelta < ThinkingSphinx::Deltas::DefaultDelta
         
     | 
| 
      
 5 
     | 
    
         
            +
              JOB_TYPES  = []
         
     | 
| 
      
 6 
     | 
    
         
            +
              JOB_PREFIX = 'ts-delta'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # LTRIM + LPOP deletes all items from the Resque queue without loading it
         
     | 
| 
      
 9 
     | 
    
         
            +
              # into client memory (unlike Resque.dequeue).
         
     | 
| 
      
 10 
     | 
    
         
            +
              # WARNING: This will clear ALL jobs in any queue used by a ResqueDelta job.
         
     | 
| 
      
 11 
     | 
    
         
            +
              # If you're sharing a queue with other jobs they'll be deleted!
         
     | 
| 
      
 12 
     | 
    
         
            +
              def self.clear_thinking_sphinx_queues
         
     | 
| 
      
 13 
     | 
    
         
            +
                JOB_TYPES.collect { |job|
         
     | 
| 
      
 14 
     | 
    
         
            +
                  job.sidekiq_options['queue']
         
     | 
| 
      
 15 
     | 
    
         
            +
                }.uniq.each do |queue|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  Sidekiq.redis { |redis| redis.srem "queues", queue }
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Sidekiq.redis { |redis| redis.del  "queue:#{queue}" }
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              # Clear both the resque queues and any other state maintained in redis
         
     | 
| 
      
 22 
     | 
    
         
            +
              def self.clear!
         
     | 
| 
      
 23 
     | 
    
         
            +
                self.clear_thinking_sphinx_queues
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                FlagAsDeletedSet.clear_all!
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              # Use simplistic locking.  We're assuming that the user won't run more than one
         
     | 
| 
      
 29 
     | 
    
         
            +
              # `rake ts:si` or `rake ts:in` task at a time.
         
     | 
| 
      
 30 
     | 
    
         
            +
              def self.lock(index_name)
         
     | 
| 
      
 31 
     | 
    
         
            +
                Sidekiq.redis {|redis|
         
     | 
| 
      
 32 
     | 
    
         
            +
                  redis.set("#{JOB_PREFIX}:index:#{index_name}:locked", 'true')
         
     | 
| 
      
 33 
     | 
    
         
            +
                }
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def self.unlock(index_name)
         
     | 
| 
      
 37 
     | 
    
         
            +
                Sidekiq.redis {|redis|
         
     | 
| 
      
 38 
     | 
    
         
            +
                  redis.del("#{JOB_PREFIX}:index:#{index_name}:locked")
         
     | 
| 
      
 39 
     | 
    
         
            +
                }
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def self.locked?(index_name)
         
     | 
| 
      
 43 
     | 
    
         
            +
                Sidekiq.redis {|redis|
         
     | 
| 
      
 44 
     | 
    
         
            +
                  redis.get("#{JOB_PREFIX}:index:#{index_name}:locked") == 'true'
         
     | 
| 
      
 45 
     | 
    
         
            +
                }
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              def delete(index, instance)
         
     | 
| 
      
 49 
     | 
    
         
            +
                return if self.class.locked?(index.reference)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                ThinkingSphinx::Deltas::SidekiqDelta::FlagAsDeletedJob.perform_async(
         
     | 
| 
      
 52 
     | 
    
         
            +
                  index.name, index.document_id_for_key(instance.id)
         
     | 
| 
      
 53 
     | 
    
         
            +
                )
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              def index(index)
         
     | 
| 
      
 57 
     | 
    
         
            +
                return if self.class.locked?(index.reference)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                ThinkingSphinx::Deltas::SidekiqDelta::DeltaJob.perform_async(index.name)
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            require 'thinking_sphinx/deltas/sidekiq_delta/delta_job'
         
     | 
| 
      
 64 
     | 
    
         
            +
            require 'thinking_sphinx/deltas/sidekiq_delta/flag_as_deleted_job'
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # A simple job class that processes a given index.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            class ThinkingSphinx::Deltas::SidekiqDelta::DeltaJob
         
     | 
| 
      
 4 
     | 
    
         
            +
              include Sidekiq::Worker
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              sidekiq_options unique: true, retry: true, queue: 'ts_delta'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # Runs Sphinx's indexer tool to process the index.
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @param [String] index the name of the Sphinx index
         
     | 
| 
      
 11 
     | 
    
         
            +
              #
         
     | 
| 
      
 12 
     | 
    
         
            +
              def perform(index)
         
     | 
| 
      
 13 
     | 
    
         
            +
                config = ThinkingSphinx::Configuration.instance
         
     | 
| 
      
 14 
     | 
    
         
            +
                config.controller.index index, :verbose => !config.settings['quiet_deltas']
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # Try again later if lock is in use.
         
     | 
| 
      
 18 
     | 
    
         
            +
              def self.lock_failed(*arguments)
         
     | 
| 
      
 19 
     | 
    
         
            +
                self.class.perform_async(*arguments)
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              # This allows us to have a concurrency safe version of ts-delayed-delta's
         
     | 
| 
      
 23 
     | 
    
         
            +
              # duplicates_exist:
         
     | 
| 
      
 24 
     | 
    
         
            +
              #
         
     | 
| 
      
 25 
     | 
    
         
            +
              # http://github.com/freelancing-god/ts-delayed-delta/blob/master/lib/thinkin
         
     | 
| 
      
 26 
     | 
    
         
            +
              # g_sphinx/deltas/delayed_delta/job.rb#L47
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              # The name of this method ensures that it runs within around_perform_lock.
         
     | 
| 
      
 29 
     | 
    
         
            +
              #
         
     | 
| 
      
 30 
     | 
    
         
            +
              # We've leveraged resque-lock-timeout to ensure that only one DeltaJob is
         
     | 
| 
      
 31 
     | 
    
         
            +
              # running at a time. Now, this around filter essentially ensures that only
         
     | 
| 
      
 32 
     | 
    
         
            +
              # one DeltaJob of each index type can sit at the queue at once. If the queue
         
     | 
| 
      
 33 
     | 
    
         
            +
              # has more than one, lrem will clear the rest off.
         
     | 
| 
      
 34 
     | 
    
         
            +
              #
         
     | 
| 
      
 35 
     | 
    
         
            +
              def self.around_perform_lock1(*arguments)
         
     | 
| 
      
 36 
     | 
    
         
            +
                # Remove all other instances of this job (with the same args) from the
         
     | 
| 
      
 37 
     | 
    
         
            +
                # queue. Uses LREM (http://code.google.com/p/redis/wiki/LremCommand) which
         
     | 
| 
      
 38 
     | 
    
         
            +
                # takes the form: "LREM key count value" and if count == 0 removes all
         
     | 
| 
      
 39 
     | 
    
         
            +
                # instances of value from the list.
         
     | 
| 
      
 40 
     | 
    
         
            +
                redis_job_value = {:class => self.to_s, :args => arguments}.to_json
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                Sidekiq.redis {|redis|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  redis.lrem("queue:#{@queue}", 0, redis_job_value)
         
     | 
| 
      
 44 
     | 
    
         
            +
                }
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                yield
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            ThinkingSphinx::Deltas::SidekiqDelta::JOB_TYPES <<
         
     | 
| 
      
 51 
     | 
    
         
            +
              ThinkingSphinx::Deltas::SidekiqDelta::DeltaJob
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class ThinkingSphinx::Deltas::SidekiqDelta::FlagAsDeletedJob
         
     | 
| 
      
 2 
     | 
    
         
            +
              include Sidekiq::Worker
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              # Runs Sphinx's indexer tool to process the index. Currently assumes Sphinx
         
     | 
| 
      
 5 
     | 
    
         
            +
              # is running.
         
     | 
| 
      
 6 
     | 
    
         
            +
              sidekiq_options unique: true, retry: true, queue: 'ts_delta'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def perform(index, document_id)
         
     | 
| 
      
 9 
     | 
    
         
            +
                ThinkingSphinx::Connection.pool.take do |connection|
         
     | 
| 
      
 10 
     | 
    
         
            +
                  connection.query(
         
     | 
| 
      
 11 
     | 
    
         
            +
                    Riddle::Query.update(index, document_id, :sphinx_deleted => true)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  )
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              rescue Mysql2::Error => error
         
     | 
| 
      
 15 
     | 
    
         
            +
                # This isn't vital, so don't raise the error
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ThinkingSphinx::Deltas::SidekiqDelta::JOB_TYPES <<
         
     | 
| 
      
 20 
     | 
    
         
            +
              ThinkingSphinx::Deltas::SidekiqDelta::FlagAsDeletedJob
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'thinking_sphinx/deltas/sidekiq_delta'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            namespace :thinking_sphinx do
         
     | 
| 
      
 4 
     | 
    
         
            +
              desc 'Lock all delta indices (Resque will not run indexer or place new jobs on the :ts_delta queue).'
         
     | 
| 
      
 5 
     | 
    
         
            +
              task :lock_deltas do
         
     | 
| 
      
 6 
     | 
    
         
            +
                ThinkingSphinx::Deltas::SidekiqDelta::CoreIndex.new.lock_deltas
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              desc 'Unlock all delta indices.'
         
     | 
| 
      
 10 
     | 
    
         
            +
              task :unlock_deltas do
         
     | 
| 
      
 11 
     | 
    
         
            +
                ThinkingSphinx::Deltas::SidekiqDelta::CoreIndex.new.unlock_deltas
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              desc 'Like `rake thinking_sphinx:index`, but locks one index at a time.'
         
     | 
| 
      
 15 
     | 
    
         
            +
              task :smart_index => :app_env do
         
     | 
| 
      
 16 
     | 
    
         
            +
                ret = ThinkingSphinx::Deltas::SidekiqDelta::CoreIndex.new.smart_index
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                abort("Indexing failed.") if ret != true
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            namespace :ts do
         
     | 
| 
      
 23 
     | 
    
         
            +
              desc 'Like `rake thinking_sphinx:index`, but locks one index at a time.'
         
     | 
| 
      
 24 
     | 
    
         
            +
              task :si => 'thinking_sphinx:smart_index'
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            unless Rake::Task.task_defined?('ts:index')
         
     | 
| 
      
 28 
     | 
    
         
            +
              require 'thinking_sphinx/tasks'
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # Ensure that indexing does not conflict with ts-resque-delta delta jobs.
         
     | 
| 
      
 32 
     | 
    
         
            +
            # Rake::Task['ts:index'].enhance ['thinking_sphinx:lock_deltas'] do
         
     | 
| 
      
 33 
     | 
    
         
            +
            #   Rake::Task['thinking_sphinx:unlock_deltas'].invoke
         
     | 
| 
      
 34 
     | 
    
         
            +
            # end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            # Rake::Task['ts:reindex'].enhance ['thinking_sphinx:lock_deltas'] do
         
     | 
| 
      
 37 
     | 
    
         
            +
            #   Rake::Task['thinking_sphinx:unlock_deltas'].invoke
         
     | 
| 
      
 38 
     | 
    
         
            +
            # end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'acceptance/spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe 'SQL delta indexing', :live => true do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before :each do
         
     | 
| 
      
 5 
     | 
    
         
            +
                Sidekiq.redis = { url: "resque://localhost:6379/", namespace: 'test' }
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              it "automatically indexes new records" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                guards = Book.create(
         
     | 
| 
      
 10 
     | 
    
         
            +
                  :title => 'Guards! Guards!', :author => 'Terry Pratchett'
         
     | 
| 
      
 11 
     | 
    
         
            +
                )
         
     | 
| 
      
 12 
     | 
    
         
            +
                index
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                Book.search('Terry Pratchett').to_a.should == [guards]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                men = Book.create(
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :title => 'Men At Arms', :author => 'Terry Pratchett'
         
     | 
| 
      
 18 
     | 
    
         
            +
                )
         
     | 
| 
      
 19 
     | 
    
         
            +
                work
         
     | 
| 
      
 20 
     | 
    
         
            +
                sleep 0.25
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                Book.search('Terry Pratchett').to_a.should == [guards, men]
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              it "automatically indexes updated records" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                book = Book.create :title => 'Night Watch', :author => 'Harry Pritchett'
         
     | 
| 
      
 27 
     | 
    
         
            +
                index
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                Book.search('Harry').to_a.should == [book]
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                book.reload.update_attributes(:author => 'Terry Pratchett')
         
     | 
| 
      
 32 
     | 
    
         
            +
                work
         
     | 
| 
      
 33 
     | 
    
         
            +
                sleep 0.25
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                Book.search('Terry').to_a.should == [book]
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              it "does not match on old values" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                book = Book.create :title => 'Night Watch', :author => 'Harry Pritchett'
         
     | 
| 
      
 40 
     | 
    
         
            +
                index
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                Book.search('Harry').to_a.should == [book]
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                book.reload.update_attributes(:author => 'Terry Pratchett')
         
     | 
| 
      
 45 
     | 
    
         
            +
                work
         
     | 
| 
      
 46 
     | 
    
         
            +
                sleep 0.25
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                Book.search('Harry').should be_empty
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class SphinxController
         
     | 
| 
      
 2 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 3 
     | 
    
         
            +
                config.searchd.mysql41 = 9307
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 7 
     | 
    
         
            +
                FileUtils.mkdir_p config.indices_location
         
     | 
| 
      
 8 
     | 
    
         
            +
                config.render_to_file && index
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                ThinkingSphinx::Configuration.reset
         
     | 
| 
      
 11 
     | 
    
         
            +
                ActiveSupport::Dependencies.clear
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                config.index_paths.each do |path|
         
     | 
| 
      
 14 
     | 
    
         
            +
                  Dir["#{path}/**/*.rb"].each { |file| $LOADED_FEATURES.delete file }
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                config.searchd.mysql41 = 9307
         
     | 
| 
      
 18 
     | 
    
         
            +
                config.settings['quiet_deltas']      = true
         
     | 
| 
      
 19 
     | 
    
         
            +
                config.settings['attribute_updates'] = true
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def start
         
     | 
| 
      
 23 
     | 
    
         
            +
                config.controller.start
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def stop
         
     | 
| 
      
 27 
     | 
    
         
            +
                config.controller.stop
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def index(*indices)
         
     | 
| 
      
 31 
     | 
    
         
            +
                config.controller.index *indices
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              private
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def config
         
     | 
| 
      
 37 
     | 
    
         
            +
                ThinkingSphinx::Configuration.instance
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SphinxHelpers
         
     | 
| 
      
 2 
     | 
    
         
            +
              include Sidekiq::Util
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def sphinx
         
     | 
| 
      
 5 
     | 
    
         
            +
                @sphinx ||= SphinxController.new
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def index(*indices)
         
     | 
| 
      
 9 
     | 
    
         
            +
                yield if block_given?
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                ThinkingSphinx::Deltas::SidekiqDelta.clear_thinking_sphinx_queues
         
     | 
| 
      
 12 
     | 
    
         
            +
                sphinx.index *indices
         
     | 
| 
      
 13 
     | 
    
         
            +
                sleep 0.25
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def work
         
     | 
| 
      
 17 
     | 
    
         
            +
                client    = Redis.connect(:url => "resque://localhost:6379/")
         
     | 
| 
      
 18 
     | 
    
         
            +
                namespace = Redis::Namespace.new('test', :redis => client)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                Sidekiq::Client.registered_queues.each do |queue_name|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  while message = namespace.lpop("queue:#{queue_name}")
         
     | 
| 
      
 22 
     | 
    
         
            +
                    message = JSON.parse(message)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    message['class'].constantize.new.perform(*message['args'])
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 30 
     | 
    
         
            +
              config.include SphinxHelpers
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              config.before :all do |group|
         
     | 
| 
      
 33 
     | 
    
         
            +
                sphinx.setup && sphinx.start if group.class.metadata[:live]
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              config.after :all do |group|
         
     | 
| 
      
 37 
     | 
    
         
            +
                sphinx.stop if group.class.metadata[:live]
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ActiveRecord::Schema.define do
         
     | 
| 
      
 2 
     | 
    
         
            +
              create_table(:books, :force => true) do |t|
         
     | 
| 
      
 3 
     | 
    
         
            +
                t.string  :title
         
     | 
| 
      
 4 
     | 
    
         
            +
                t.string  :author
         
     | 
| 
      
 5 
     | 
    
         
            +
                t.integer :year
         
     | 
| 
      
 6 
     | 
    
         
            +
                t.string  :blurb_file
         
     | 
| 
      
 7 
     | 
    
         
            +
                t.boolean :delta, :default => true, :null => false
         
     | 
| 
      
 8 
     | 
    
         
            +
                t.timestamps
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              create_table(:delayed_jobs, :force => true) do |t|
         
     | 
| 
      
 12 
     | 
    
         
            +
                t.column :priority, :integer, :default => 0
         
     | 
| 
      
 13 
     | 
    
         
            +
                t.column :attempts, :integer, :default => 0
         
     | 
| 
      
 14 
     | 
    
         
            +
                t.column :handler, :text
         
     | 
| 
      
 15 
     | 
    
         
            +
                t.column :last_error, :text
         
     | 
| 
      
 16 
     | 
    
         
            +
                t.column :run_at, :datetime
         
     | 
| 
      
 17 
     | 
    
         
            +
                t.column :locked_at, :datetime
         
     | 
| 
      
 18 
     | 
    
         
            +
                t.column :failed_at, :datetime
         
     | 
| 
      
 19 
     | 
    
         
            +
                t.column :locked_by, :string
         
     | 
| 
      
 20 
     | 
    
         
            +
                t.column :queue, :string
         
     | 
| 
      
 21 
     | 
    
         
            +
                t.column :created_at, :datetime
         
     | 
| 
      
 22 
     | 
    
         
            +
                t.column :updated_at, :datetime
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            *.log
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'bundler'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Bundler.require :default, :development
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'thinking_sphinx/railtie'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Combustion.initialize! :active_record
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            root = File.expand_path File.dirname(__FILE__)
         
     | 
| 
      
 11 
     | 
    
         
            +
            Dir["#{root}/support/**/*.rb"].each { |file| require file }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 14 
     | 
    
         
            +
              # enable filtering for examples
         
     | 
| 
      
 15 
     | 
    
         
            +
              config.filter_run :wip => nil
         
     | 
| 
      
 16 
     | 
    
         
            +
              config.run_all_when_everything_filtered = true
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
    
        data/tasks/rails.rake
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), '/../lib/thinking_sphinx/deltas/resque_delta/tasks')
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 3 
     | 
    
         
            +
              s.name        = 'ts-sidekiq-delta'
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.version     = '0.1.0'
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.platform    = Gem::Platform::RUBY
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.authors     = ['Pat Allan', 'Aaron Gibralter', 'Danny Hawkins']
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.email       = ['pat@freelancing-gods.com', 'danny.hawkins@gmail.com']
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.homepage    = 'https://github.com/pat/ts-sidekiq-delta'
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.summary     = %q{Thinking Sphinx - Sidekiq Deltas}
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.description = %q{Manage delta indexes via Sidekiq for Thinking Sphinx}
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.license     = 'MIT'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              s.files         = `git ls-files`.split("\n")
         
     | 
| 
      
 14 
     | 
    
         
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         
     | 
| 
      
 15 
     | 
    
         
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              s.add_dependency 'thinking-sphinx', '>= 3.0.0'
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.add_dependency 'sidekiq',         '>= 2.5.4'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              s.add_development_dependency 'activerecord',     '>= 3.1.0'
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_development_dependency 'database_cleaner', '>= 0.5.2'
         
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_development_dependency 'mysql2',           '>= 0.3.12b4'
         
     | 
| 
      
 24 
     | 
    
         
            +
              s.add_development_dependency 'rake',             '>= 0.8.7'
         
     | 
| 
      
 25 
     | 
    
         
            +
              s.add_development_dependency 'rspec',            '>= 2.11.0'
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,204 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: ts-sidekiq-delta
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Pat Allan
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Aaron Gibralter
         
     | 
| 
      
 9 
     | 
    
         
            +
            - Danny Hawkins
         
     | 
| 
      
 10 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 11 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 12 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            date: 2013-12-02 00:00:00.000000000 Z
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 15 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 16 
     | 
    
         
            +
              name: thinking-sphinx
         
     | 
| 
      
 17 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 18 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 19 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 20 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 21 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
      
 22 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 25 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 26 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 27 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 28 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
      
 29 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 30 
     | 
    
         
            +
              name: sidekiq
         
     | 
| 
      
 31 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 32 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 33 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 34 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 35 
     | 
    
         
            +
                    version: 2.5.4
         
     | 
| 
      
 36 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 37 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 38 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 39 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 40 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 41 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 42 
     | 
    
         
            +
                    version: 2.5.4
         
     | 
| 
      
 43 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 44 
     | 
    
         
            +
              name: activerecord
         
     | 
| 
      
 45 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 46 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 47 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 48 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 49 
     | 
    
         
            +
                    version: 3.1.0
         
     | 
| 
      
 50 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 51 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 52 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 53 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 54 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 55 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 56 
     | 
    
         
            +
                    version: 3.1.0
         
     | 
| 
      
 57 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 58 
     | 
    
         
            +
              name: database_cleaner
         
     | 
| 
      
 59 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 60 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 61 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 62 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 63 
     | 
    
         
            +
                    version: 0.5.2
         
     | 
| 
      
 64 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 65 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 66 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 67 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 68 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 69 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 70 
     | 
    
         
            +
                    version: 0.5.2
         
     | 
| 
      
 71 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 72 
     | 
    
         
            +
              name: mysql2
         
     | 
| 
      
 73 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 74 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 75 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 76 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 77 
     | 
    
         
            +
                    version: 0.3.12b4
         
     | 
| 
      
 78 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 79 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 80 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 81 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 82 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 83 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 84 
     | 
    
         
            +
                    version: 0.3.12b4
         
     | 
| 
      
 85 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 86 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 87 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 88 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 89 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 90 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 91 
     | 
    
         
            +
                    version: 0.8.7
         
     | 
| 
      
 92 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 93 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 94 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 95 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 96 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 97 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 98 
     | 
    
         
            +
                    version: 0.8.7
         
     | 
| 
      
 99 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 100 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 101 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 102 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 103 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 104 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 105 
     | 
    
         
            +
                    version: 2.11.0
         
     | 
| 
      
 106 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 107 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 108 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 109 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 110 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 111 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 112 
     | 
    
         
            +
                    version: 2.11.0
         
     | 
| 
      
 113 
     | 
    
         
            +
            description: Manage delta indexes via Sidekiq for Thinking Sphinx
         
     | 
| 
      
 114 
     | 
    
         
            +
            email:
         
     | 
| 
      
 115 
     | 
    
         
            +
            - pat@freelancing-gods.com
         
     | 
| 
      
 116 
     | 
    
         
            +
            - danny.hawkins@gmail.com
         
     | 
| 
      
 117 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 118 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 119 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 120 
     | 
    
         
            +
            files:
         
     | 
| 
      
 121 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 122 
     | 
    
         
            +
            - .rspec
         
     | 
| 
      
 123 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 124 
     | 
    
         
            +
            - Guardfile
         
     | 
| 
      
 125 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 126 
     | 
    
         
            +
            - README.markdown
         
     | 
| 
      
 127 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 128 
     | 
    
         
            +
            - config/redis-cucumber.conf
         
     | 
| 
      
 129 
     | 
    
         
            +
            - cucumber.yml
         
     | 
| 
      
 130 
     | 
    
         
            +
            - features/sidekiq_deltas.feature
         
     | 
| 
      
 131 
     | 
    
         
            +
            - features/smart_indexing.feature
         
     | 
| 
      
 132 
     | 
    
         
            +
            - features/step_definitions/common_steps.rb
         
     | 
| 
      
 133 
     | 
    
         
            +
            - features/step_definitions/sidekiq_delta_steps.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - features/step_definitions/smart_indexing_steps.rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - features/support/env.rb
         
     | 
| 
      
 136 
     | 
    
         
            +
            - features/thinking_sphinx/database.example.yml
         
     | 
| 
      
 137 
     | 
    
         
            +
            - features/thinking_sphinx/db/migrations/create_delayed_betas.rb
         
     | 
| 
      
 138 
     | 
    
         
            +
            - features/thinking_sphinx/models/delayed_beta.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - lib/thinking_sphinx/deltas/sidekiq_delta.rb
         
     | 
| 
      
 140 
     | 
    
         
            +
            - lib/thinking_sphinx/deltas/sidekiq_delta/delta_job.rb
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib/thinking_sphinx/deltas/sidekiq_delta/flag_as_deleted_job.rb
         
     | 
| 
      
 142 
     | 
    
         
            +
            - lib/thinking_sphinx/deltas/sidekiq_delta/railtie.rb
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/thinking_sphinx/deltas/sidekiq_delta/tasks.rb
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/ts-sidekiq-delta.rb
         
     | 
| 
      
 145 
     | 
    
         
            +
            - spec/acceptance/sidekiq_deltas_spec.rb
         
     | 
| 
      
 146 
     | 
    
         
            +
            - spec/acceptance/spec_helper.rb
         
     | 
| 
      
 147 
     | 
    
         
            +
            - spec/acceptance/support/database_cleaner.rb
         
     | 
| 
      
 148 
     | 
    
         
            +
            - spec/acceptance/support/sphinx_controller.rb
         
     | 
| 
      
 149 
     | 
    
         
            +
            - spec/acceptance/support/sphinx_helpers.rb
         
     | 
| 
      
 150 
     | 
    
         
            +
            - spec/internal/.gitignore
         
     | 
| 
      
 151 
     | 
    
         
            +
            - spec/internal/app/indices/book_index.rb
         
     | 
| 
      
 152 
     | 
    
         
            +
            - spec/internal/app/models/book.rb
         
     | 
| 
      
 153 
     | 
    
         
            +
            - spec/internal/config/database.yml
         
     | 
| 
      
 154 
     | 
    
         
            +
            - spec/internal/db/schema.rb
         
     | 
| 
      
 155 
     | 
    
         
            +
            - spec/internal/log/.gitignore
         
     | 
| 
      
 156 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 157 
     | 
    
         
            +
            - tasks/rails.rake
         
     | 
| 
      
 158 
     | 
    
         
            +
            - ts-sidekiq-delta.gemspec
         
     | 
| 
      
 159 
     | 
    
         
            +
            homepage: https://github.com/pat/ts-sidekiq-delta
         
     | 
| 
      
 160 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 161 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 162 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 163 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 164 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 165 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 166 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 167 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 168 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 169 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 170 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 171 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 172 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 173 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 174 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 175 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 176 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 177 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 178 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 179 
     | 
    
         
            +
            rubygems_version: 2.1.11
         
     | 
| 
      
 180 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 181 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 182 
     | 
    
         
            +
            summary: Thinking Sphinx - Sidekiq Deltas
         
     | 
| 
      
 183 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 184 
     | 
    
         
            +
            - features/sidekiq_deltas.feature
         
     | 
| 
      
 185 
     | 
    
         
            +
            - features/smart_indexing.feature
         
     | 
| 
      
 186 
     | 
    
         
            +
            - features/step_definitions/common_steps.rb
         
     | 
| 
      
 187 
     | 
    
         
            +
            - features/step_definitions/sidekiq_delta_steps.rb
         
     | 
| 
      
 188 
     | 
    
         
            +
            - features/step_definitions/smart_indexing_steps.rb
         
     | 
| 
      
 189 
     | 
    
         
            +
            - features/support/env.rb
         
     | 
| 
      
 190 
     | 
    
         
            +
            - features/thinking_sphinx/database.example.yml
         
     | 
| 
      
 191 
     | 
    
         
            +
            - features/thinking_sphinx/db/migrations/create_delayed_betas.rb
         
     | 
| 
      
 192 
     | 
    
         
            +
            - features/thinking_sphinx/models/delayed_beta.rb
         
     | 
| 
      
 193 
     | 
    
         
            +
            - spec/acceptance/sidekiq_deltas_spec.rb
         
     | 
| 
      
 194 
     | 
    
         
            +
            - spec/acceptance/spec_helper.rb
         
     | 
| 
      
 195 
     | 
    
         
            +
            - spec/acceptance/support/database_cleaner.rb
         
     | 
| 
      
 196 
     | 
    
         
            +
            - spec/acceptance/support/sphinx_controller.rb
         
     | 
| 
      
 197 
     | 
    
         
            +
            - spec/acceptance/support/sphinx_helpers.rb
         
     | 
| 
      
 198 
     | 
    
         
            +
            - spec/internal/.gitignore
         
     | 
| 
      
 199 
     | 
    
         
            +
            - spec/internal/app/indices/book_index.rb
         
     | 
| 
      
 200 
     | 
    
         
            +
            - spec/internal/app/models/book.rb
         
     | 
| 
      
 201 
     | 
    
         
            +
            - spec/internal/config/database.yml
         
     | 
| 
      
 202 
     | 
    
         
            +
            - spec/internal/db/schema.rb
         
     | 
| 
      
 203 
     | 
    
         
            +
            - spec/internal/log/.gitignore
         
     | 
| 
      
 204 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     |