processor 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.travis.yml +1 -0
- data/README.md +26 -7
- data/lib/processor/data/batch_processor.rb +6 -3
- data/lib/processor/data/solr_pages_processor.rb +1 -1
- data/lib/processor/observer/logger.rb +16 -14
- data/lib/processor/observer/null_observer.rb +1 -1
- data/lib/processor/process_runner/threads.rb +7 -1
- data/lib/processor/thread.rb +0 -1
- data/lib/processor/version.rb +1 -1
- data/lib/processor.rb +4 -0
- data/processor.gemspec +2 -2
- data/spec/processor/data/batch_processor_spec.rb +17 -13
- data/spec/processor/observer/logger_spec.rb +31 -0
- data/spec/processor/process_runner/specs.rb +13 -2
- metadata +8 -25
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            !binary "U0hBMQ==":
         | 
| 3 | 
            +
              metadata.gz: !binary |-
         | 
| 4 | 
            +
                MzUxNDQ3NmM4YzZhOTk5Njc0MjVmNThiNDJhYTlhZWQ0NjhkNjJlOQ==
         | 
| 5 | 
            +
              data.tar.gz: !binary |-
         | 
| 6 | 
            +
                MWExYTAxNjk0MDU3MGRiMDc3NmE3NzA0MzNkZjMzMTYxZTEwY2I3OA==
         | 
| 7 | 
            +
            SHA512:
         | 
| 8 | 
            +
              metadata.gz: !binary |-
         | 
| 9 | 
            +
                NzcxYTA0Y2UyYTU4OGNiYTA0YjkxMDdlODE5YTQ2ZjRhZDA3ZGY0ODM0MWY5
         | 
| 10 | 
            +
                N2Y5NzY3MzI4MTZiN2UyMDY0NDgwYzQ1N2E1NDIxNmU2NmM4Y2I0ZmE5YjI1
         | 
| 11 | 
            +
                NGU2ZjIwZTU1OWVmNjRmM2FhODY1ODFiOTBmODI5ZWI0MWExNGU=
         | 
| 12 | 
            +
              data.tar.gz: !binary |-
         | 
| 13 | 
            +
                MWQ3MWIyZGIzZGVhYzA1ZWJkYjlhOWM5NzE0MDIzZDRhNjE2NmI0MGE5OTk5
         | 
| 14 | 
            +
                N2FhZTBiMzViNDY0MTM1NWMyNGNkZDI1ZTNjZDcxYjA5OTgzMzBjZThkMTNk
         | 
| 15 | 
            +
                NzNmOWE2YjdhNDMwZmE1YmM5MjU3N2Q4ZmZiZWRlNjAzM2MwZjI=
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -5,18 +5,18 @@ Processor | |
| 5 5 | 
             
            [](https://coveralls.io/r/AlexParamonov/processor?branch=master)
         | 
| 6 6 |  | 
| 7 7 |  | 
| 8 | 
            -
            Processor is a tool that helps to iterate over collection and
         | 
| 8 | 
            +
            Processor is a tool that helps to iterate over a collection and
         | 
| 9 9 | 
             
            perform complex actions on a result. It is extremely useful in data
         | 
| 10 10 | 
             
            migrations, report generation, etc.
         | 
| 11 11 |  | 
| 12 12 | 
             
            Collection could be iteratively fetched by parts but for processor
         | 
| 13 13 | 
             
            it will looks like an endless collection. There are a lot such tiny
         | 
| 14 14 | 
             
            goodness that makes usage of processor pleasant. Need logging,
         | 
| 15 | 
            -
            exception processing, post/pre processing a result  | 
| 15 | 
            +
            exception processing, post/pre processing a result? No problem - all
         | 
| 16 16 | 
             
            included and easily extended.
         | 
| 17 17 |  | 
| 18 | 
            -
            Use the processor to DRY your migrations,  | 
| 19 | 
            -
            logging and post processing.
         | 
| 18 | 
            +
            Use the processor to DRY your migrations, reports and to stop mess
         | 
| 19 | 
            +
            with logging and post processing.
         | 
| 20 20 |  | 
| 21 21 | 
             
            Did I mentioned you can run in threads as easy as say
         | 
| 22 22 | 
             
            `processor.run_in_threads 10`?
         | 
| @@ -36,8 +36,8 @@ Contents | |
| 36 36 | 
             
                1. Data processors
         | 
| 37 37 | 
             
                1. Subroutines
         | 
| 38 38 | 
             
                1. Run modes
         | 
| 39 | 
            -
                1. Processor Thread
         | 
| 40 39 | 
             
                1. Observers
         | 
| 40 | 
            +
                1. Processor Thread
         | 
| 41 41 | 
             
            1. Contacts
         | 
| 42 42 | 
             
            1. Compatibility
         | 
| 43 43 | 
             
            1. Contributing
         | 
| @@ -45,17 +45,20 @@ Contents | |
| 45 45 |  | 
| 46 46 | 
             
            Installation
         | 
| 47 47 | 
             
            ------------
         | 
| 48 | 
            -
             | 
| 48 | 
            +
            If on Rails, add this line to your application's Gemfile:
         | 
| 49 | 
            +
             | 
| 49 50 | 
             
            ``` ruby
         | 
| 50 51 | 
             
            gem 'processor'
         | 
| 51 52 | 
             
            ```
         | 
| 52 53 |  | 
| 53 54 | 
             
            And then execute:
         | 
| 55 | 
            +
             | 
| 54 56 | 
             
            ``` sh
         | 
| 55 57 | 
             
            bundle
         | 
| 56 58 | 
             
            ```
         | 
| 57 59 |  | 
| 58 | 
            -
            Or install it yourself | 
| 60 | 
            +
            Or install it yourself:
         | 
| 61 | 
            +
             | 
| 59 62 | 
             
            ``` sh
         | 
| 60 63 | 
             
            gem install processor
         | 
| 61 64 | 
             
            ```
         | 
| @@ -148,6 +151,7 @@ It runs `process` one by one for each found record returned by | |
| 148 151 | 
             
            `records` method.
         | 
| 149 152 |  | 
| 150 153 | 
             
            Call it using a `Processor::Thread`:
         | 
| 154 | 
            +
             | 
| 151 155 | 
             
            ``` ruby
         | 
| 152 156 | 
             
            Processor::Thread.new(migration).run_successive
         | 
| 153 157 | 
             
            ```
         | 
| @@ -158,15 +162,20 @@ not waiting for previous `process` to finish. | |
| 158 162 |  | 
| 159 163 | 
             
            Possible to specify number of threads used by passing a number to
         | 
| 160 164 | 
             
            constructor:
         | 
| 165 | 
            +
             | 
| 161 166 | 
             
            ``` ruby
         | 
| 162 167 | 
             
            Processor::ProcessRunner::Threads.new 5
         | 
| 163 168 | 
             
            ```
         | 
| 164 169 |  | 
| 165 170 | 
             
            Call it using a `Processor::Thread`:
         | 
| 171 | 
            +
             | 
| 166 172 | 
             
            ``` ruby
         | 
| 167 173 | 
             
            Processor::Thread.new(migration).run_in_threads 5
         | 
| 168 174 | 
             
            ```
         | 
| 169 175 |  | 
| 176 | 
            +
            Note: on MRI ruby you could expect perfomance gain using threads if
         | 
| 177 | 
            +
            your application has resource consuming IO operations
         | 
| 178 | 
            +
             | 
| 170 179 |  | 
| 171 180 | 
             
            ### Observers
         | 
| 172 181 | 
             
            Processor support unlimited number of observers that are watching
         | 
| @@ -191,16 +200,19 @@ Read below section Processor Thread to see how to use observers in runner. | |
| 191 200 | 
             
            Processor classes and provides __stable__ interface.
         | 
| 192 201 |  | 
| 193 202 | 
             
            Creating a new Thread:
         | 
| 203 | 
            +
             | 
| 194 204 | 
             
            ``` ruby
         | 
| 195 205 | 
             
            Processor::Thread.new data_processor
         | 
| 196 206 | 
             
            ```
         | 
| 197 207 |  | 
| 198 208 | 
             
            You may provide optional observers:
         | 
| 209 | 
            +
             | 
| 199 210 | 
             
            ``` ruby
         | 
| 200 211 | 
             
            Processor::Thread.new data_processor, observer1, observer2, ...
         | 
| 201 212 | 
             
            ```
         | 
| 202 213 |  | 
| 203 214 | 
             
            Instance have a `run_as` method that accepts a block:
         | 
| 215 | 
            +
             | 
| 204 216 | 
             
            ``` ruby
         | 
| 205 217 | 
             
            thread = Processor::Thread.new @migration
         | 
| 206 218 | 
             
            thread.run_as do |processor|
         | 
| @@ -211,6 +223,7 @@ end | |
| 211 223 | 
             
            ```
         | 
| 212 224 |  | 
| 213 225 | 
             
            Instance have a `run_successive` method: 
         | 
| 226 | 
            +
             | 
| 214 227 | 
             
            ``` ruby
         | 
| 215 228 | 
             
            data_processor = UserLocationMigration.new
         | 
| 216 229 | 
             
            thread = Processor::Thread.new data_processor
         | 
| @@ -218,6 +231,7 @@ thread.run_successive | |
| 218 231 | 
             
            ```
         | 
| 219 232 |  | 
| 220 233 | 
             
            And `run_in_threads` method:
         | 
| 234 | 
            +
             | 
| 221 235 | 
             
            ``` ruby
         | 
| 222 236 | 
             
            data_processor = UserCsvImport.new csv_file
         | 
| 223 237 | 
             
            thread = Processor::Thread.new data_processor
         | 
| @@ -228,6 +242,7 @@ See `spec/processor/thread_spec.rb` and `spec/example_spec.rb` and | |
| 228 242 | 
             
            `example` directory for other usage examples.
         | 
| 229 243 |  | 
| 230 244 | 
             
            It is recommended to wrap Processor::Thread by classes named like:
         | 
| 245 | 
            +
             | 
| 231 246 | 
             
            ``` ruby
         | 
| 232 247 | 
             
            WeeklyReport
         | 
| 233 248 | 
             
            TaxonomyMigration
         | 
| @@ -236,6 +251,7 @@ UserDataImport | |
| 236 251 |  | 
| 237 252 | 
             
            The point is to hide configuration of observers and use (if you wish)
         | 
| 238 253 | 
             
            your own API to run reports or migrations:
         | 
| 254 | 
            +
             | 
| 239 255 | 
             
            ``` ruby
         | 
| 240 256 | 
             
            weekly_report.create_and_deliver
         | 
| 241 257 | 
             
            user_data_import.from_csv(file)
         | 
| @@ -244,6 +260,7 @@ etc. | |
| 244 260 |  | 
| 245 261 | 
             
            It is possible to use it raw, but please don't fear to add a wrapper
         | 
| 246 262 | 
             
            class like `CsvUserImport` for this:
         | 
| 263 | 
            +
             | 
| 247 264 | 
             
            ``` ruby
         | 
| 248 265 | 
             
            csv_data_processor = Processor::Data::CsvProcessor.new file
         | 
| 249 266 | 
             
            stdout_notifier = Processor::Observer::Logger.new(Logger.new(STDOUT))
         | 
| @@ -257,6 +274,7 @@ Processor::Thread.new( | |
| 257 274 | 
             
            ```
         | 
| 258 275 |  | 
| 259 276 | 
             
            More documentation could be found by running
         | 
| 277 | 
            +
             | 
| 260 278 | 
             
            ``` sh
         | 
| 261 279 | 
             
            rspec
         | 
| 262 280 | 
             
            ```
         | 
| @@ -274,6 +292,7 @@ Compatibility | |
| 274 292 | 
             
            tested with Ruby
         | 
| 275 293 |  | 
| 276 294 | 
             
            * 1.9.3
         | 
| 295 | 
            +
            * 2.1.4
         | 
| 277 296 | 
             
            * rbx-19mode
         | 
| 278 297 | 
             
            * ruby-head
         | 
| 279 298 |  | 
| @@ -2,6 +2,8 @@ require_relative 'null_processor' | |
| 2 2 |  | 
| 3 3 | 
             
            module Processor
         | 
| 4 4 | 
             
              module Data
         | 
| 5 | 
            +
                # TODO: Change it to be useful.
         | 
| 6 | 
            +
                # Usually the external iterator is provided and #results are mapped to it
         | 
| 5 7 | 
             
                class BatchProcessor < NullProcessor
         | 
| 6 8 | 
             
                  def initialize(batch_size = 10)
         | 
| 7 9 | 
             
                    @batch_size = batch_size
         | 
| @@ -9,9 +11,7 @@ module Processor | |
| 9 11 |  | 
| 10 12 | 
             
                  def records
         | 
| 11 13 | 
             
                    Enumerator.new do |result|
         | 
| 12 | 
            -
                       | 
| 13 | 
            -
                        batch = fetch_batch
         | 
| 14 | 
            -
                        break if batch.count < 1
         | 
| 14 | 
            +
                      while (batch = fetch_batch).any?
         | 
| 15 15 | 
             
                        batch.each do |record|
         | 
| 16 16 | 
             
                          result << record
         | 
| 17 17 | 
             
                        end
         | 
| @@ -21,7 +21,10 @@ module Processor | |
| 21 21 |  | 
| 22 22 | 
             
                  def fetch_batch
         | 
| 23 23 | 
             
                    @fetcher ||= query.each_slice(batch_size)
         | 
| 24 | 
            +
                    # TODO get rid of .next enumeration here
         | 
| 24 25 | 
             
                    @fetcher.next
         | 
| 26 | 
            +
                  rescue StopIteration
         | 
| 27 | 
            +
                    []
         | 
| 25 28 | 
             
                  end
         | 
| 26 29 |  | 
| 27 30 | 
             
                  def total_records
         | 
| @@ -8,10 +8,16 @@ module Processor | |
| 8 8 | 
             
              module Observer
         | 
| 9 9 | 
             
                class Logger < NullObserver
         | 
| 10 10 | 
             
                  def initialize(logger = nil, options = {})
         | 
| 11 | 
            -
                     | 
| 11 | 
            +
                    if logger.is_a? Hash
         | 
| 12 | 
            +
                      @log_level = logger.fetch :level, ::Logger::INFO
         | 
| 13 | 
            +
                    else
         | 
| 14 | 
            +
                      @logger_source = logger
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
             | 
| 12 17 | 
             
                    @messages = options.fetch :messages, nil
         | 
| 13 18 | 
             
                    @messages = OpenStruct.new @messages if @messages.is_a? Hash
         | 
| 14 19 |  | 
| 20 | 
            +
             | 
| 15 21 | 
             
                    super options
         | 
| 16 22 | 
             
                  end
         | 
| 17 23 |  | 
| @@ -33,11 +39,11 @@ module Processor | |
| 33 39 | 
             
                    messenger.message messages.finished
         | 
| 34 40 | 
             
                  end
         | 
| 35 41 |  | 
| 36 | 
            -
                  def  | 
| 37 | 
            -
                    logger.error "Error processing #{id_for record}: #{exception}"
         | 
| 42 | 
            +
                  def before_record_error(record, exception)
         | 
| 43 | 
            +
                    logger.error "Error processing #{id_for record}: #{exception.inspect}"
         | 
| 38 44 | 
             
                  end
         | 
| 39 45 |  | 
| 40 | 
            -
                  def  | 
| 46 | 
            +
                  def before_error(exception)
         | 
| 41 47 | 
             
                    logger.fatal "Processing #{processor_name} FAILED: #{exception.backtrace}"
         | 
| 42 48 | 
             
                  end
         | 
| 43 49 |  | 
| @@ -47,7 +53,7 @@ module Processor | |
| 47 53 | 
             
                        @logger_source.call processor_name
         | 
| 48 54 | 
             
                      else
         | 
| 49 55 | 
             
                        @logger_source or ::Logger.new(create_log_filename(processor_name)).tap do |logger|
         | 
| 50 | 
            -
                          logger.level =  | 
| 56 | 
            +
                          logger.level = log_level
         | 
| 51 57 | 
             
                        end
         | 
| 52 58 | 
             
                      end
         | 
| 53 59 | 
             
                    end
         | 
| @@ -55,6 +61,10 @@ module Processor | |
| 55 61 |  | 
| 56 62 | 
             
                  private
         | 
| 57 63 |  | 
| 64 | 
            +
                  def log_level
         | 
| 65 | 
            +
                    @log_level ||= ::Logger::INFO
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 58 68 | 
             
                  def messages
         | 
| 59 69 | 
             
                    @messages ||= LoggerMessages.new logger
         | 
| 60 70 | 
             
                  end
         | 
| @@ -85,15 +95,7 @@ module Processor | |
| 85 95 | 
             
                  end
         | 
| 86 96 |  | 
| 87 97 | 
             
                  def id_for record
         | 
| 88 | 
            -
                     | 
| 89 | 
            -
                      return record.public_send method if record.respond_to? method
         | 
| 90 | 
            -
                    end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                    [:uid, :id, :token, :sym, :UID, :ID, :TOKEN, :SYM].each do |method|
         | 
| 93 | 
            -
                      return record[method] if record.key? method
         | 
| 94 | 
            -
                      return record[method.to_s] if record.key? method.to_s
         | 
| 95 | 
            -
                    end if record.respond_to?(:key?) && record.respond_to?(:[])
         | 
| 96 | 
            -
             | 
| 98 | 
            +
                    return processor.record_id record if processor.respond_to? :record_id
         | 
| 97 99 | 
             
                    record.to_s.strip
         | 
| 98 100 | 
             
                  end
         | 
| 99 101 | 
             
                end
         | 
| @@ -7,7 +7,7 @@ module Processor | |
| 7 7 | 
             
                  attr_reader :processor
         | 
| 8 8 |  | 
| 9 9 | 
             
                  def initialize(options = {})
         | 
| 10 | 
            -
                    @messenger = options.fetch :messenger, Processor::Messenger.new(:info,  | 
| 10 | 
            +
                    @messenger = options.fetch :messenger, Processor::Messenger.new(:info, STDERR, self.class.name)
         | 
| 11 11 | 
             
                    @processor = options.fetch :processor, nil
         | 
| 12 12 | 
             
                  end
         | 
| 13 13 |  | 
| @@ -17,7 +17,13 @@ module Processor | |
| 17 17 | 
             
                          begin
         | 
| 18 18 | 
             
                            thread_data_processor.process(thread_record)
         | 
| 19 19 | 
             
                          rescue StandardError => exception
         | 
| 20 | 
            -
                             | 
| 20 | 
            +
                            command = catch(:command) do
         | 
| 21 | 
            +
                              thread_data_processor.record_error thread_record, exception
         | 
| 22 | 
            +
                            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                            # NOTE: redo can not be moved into a method or block
         | 
| 25 | 
            +
                            # to break from records loop, use Exception
         | 
| 26 | 
            +
                            redo if command == :redo
         | 
| 21 27 | 
             
                          end
         | 
| 22 28 | 
             
                        end
         | 
| 23 29 |  | 
    
        data/lib/processor/thread.rb
    CHANGED
    
    
    
        data/lib/processor/version.rb
    CHANGED
    
    
    
        data/lib/processor.rb
    CHANGED
    
    | @@ -13,6 +13,10 @@ require "processor/observer/null_observer" | |
| 13 13 | 
             
            require "processor/process_runner/successive"
         | 
| 14 14 | 
             
            require "processor/process_runner/threads"
         | 
| 15 15 |  | 
| 16 | 
            +
            require "processor/subroutine/counter"
         | 
| 17 | 
            +
            require "processor/subroutine/recursion"
         | 
| 18 | 
            +
            require "processor/subroutine/name"
         | 
| 19 | 
            +
             | 
| 16 20 | 
             
            require "processor/runner"
         | 
| 17 21 | 
             
            require "processor/thread"
         | 
| 18 22 |  | 
    
        data/processor.gemspec
    CHANGED
    
    | @@ -9,7 +9,7 @@ Gem::Specification.new do |gem| | |
| 9 9 | 
             
              gem.version       = Processor::VERSION
         | 
| 10 10 | 
             
              gem.authors       = ["Alexander Paramonov"]
         | 
| 11 11 | 
             
              gem.email         = ["alexander.n.paramonov@gmail.com"]
         | 
| 12 | 
            -
              gem.summary       = %q{Universal processor for  | 
| 12 | 
            +
              gem.summary       = %q{Universal processor for threaded collection iteration, logging and post processing}
         | 
| 13 13 | 
             
              gem.description   = %q{Processor is a tool that helps to iterate over collection and perform complex actions on a result. It is extremely useful in data migrations, report generation, etc. }
         | 
| 14 14 | 
             
              gem.homepage      = "http://github.com/AlexParamonov/processor"
         | 
| 15 15 | 
             
              gem.license       = "MIT"
         | 
| @@ -20,7 +20,7 @@ Gem::Specification.new do |gem| | |
| 20 20 | 
             
              gem.require_paths = ["lib"]
         | 
| 21 21 |  | 
| 22 22 | 
             
              gem.add_development_dependency "rake"
         | 
| 23 | 
            -
              gem.add_development_dependency "rspec", " | 
| 23 | 
            +
              gem.add_development_dependency "rspec", "~> 2.6"
         | 
| 24 24 | 
             
              gem.add_development_dependency "pry" unless Processor::RUNNING_ON_CI
         | 
| 25 25 | 
             
              gem.add_development_dependency "pry-plus" if "ruby" == RUBY_ENGINE && false == Processor::RUNNING_ON_CI
         | 
| 26 26 | 
             
              gem.add_development_dependency "coveralls" if Processor::RUNNING_ON_CI
         | 
| @@ -6,26 +6,30 @@ describe Processor::Data::BatchProcessor do | |
| 6 6 | 
             
              it "should create and process records by batch" do
         | 
| 7 7 | 
             
                processor = Processor::Data::BatchProcessor.new 2
         | 
| 8 8 |  | 
| 9 | 
            -
                 | 
| 10 | 
            -
             | 
| 11 | 
            -
                   | 
| 12 | 
            -
             | 
| 13 | 
            -
                   | 
| 14 | 
            -
                   | 
| 15 | 
            -
             | 
| 9 | 
            +
                records = (1..10).each_slice(2).map do |first_record, second_record|
         | 
| 10 | 
            +
                  record1 = mock("record_#{first_record}")
         | 
| 11 | 
            +
                  record2 = mock("record_#{second_record}")
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  record1.should_receive(:created).ordered
         | 
| 14 | 
            +
                  record2.should_receive(:created).ordered
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  record1.should_receive(:processed).ordered
         | 
| 17 | 
            +
                  record2.should_receive(:processed).ordered
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  [ record1, record2 ]
         | 
| 20 | 
            +
                end.flatten
         | 
| 16 21 |  | 
| 17 22 | 
             
                query = Enumerator.new do |y|
         | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
                     | 
| 21 | 
            -
                    y <<  | 
| 22 | 
            -
                    a += 1
         | 
| 23 | 
            +
                  while records.any?
         | 
| 24 | 
            +
                    record = records.shift
         | 
| 25 | 
            +
                    record.created
         | 
| 26 | 
            +
                    y << record
         | 
| 23 27 | 
             
                  end
         | 
| 24 28 | 
             
                end
         | 
| 25 29 |  | 
| 26 30 | 
             
                processor.stub(query: query)
         | 
| 27 31 | 
             
                processor.records.each do |record|
         | 
| 28 | 
            -
                   | 
| 32 | 
            +
                  record.processed
         | 
| 29 33 | 
             
                end
         | 
| 30 34 | 
             
              end
         | 
| 31 35 |  | 
| @@ -9,6 +9,15 @@ describe Processor::Observer::Logger do | |
| 9 9 | 
             
              let(:messenger) { ::Logger.new("/dev/null") }
         | 
| 10 10 | 
             
              let(:logger) { ::Logger.new("/dev/null") }
         | 
| 11 11 |  | 
| 12 | 
            +
              describe "record_id" do
         | 
| 13 | 
            +
                it "uses processor.record_id if possible" do
         | 
| 14 | 
            +
                  record = double :record
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  expect(processor).to receive(:record_id).with(record).and_return 1
         | 
| 17 | 
            +
                  subject.send(:id_for, record).should eq 1
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 12 21 | 
             
              describe "logger" do
         | 
| 13 22 | 
             
                describe "as proc" do
         | 
| 14 23 | 
             
                  let(:external_logger) { stub }
         | 
| @@ -37,6 +46,28 @@ describe Processor::Observer::Logger do | |
| 37 46 | 
             
                    ::Logger.should_receive(:new).and_return(ruby_logger)
         | 
| 38 47 | 
             
                    observer.logger.should eq ruby_logger
         | 
| 39 48 | 
             
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  it "sets log level to info by default" do
         | 
| 51 | 
            +
                    observer = subject
         | 
| 52 | 
            +
                    ::Logger.any_instance.should_receive(:level=).with(::Logger::INFO)
         | 
| 53 | 
            +
                    observer.logger
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  it "sets log level to user specified value" do
         | 
| 57 | 
            +
                    observer = described_class.new level: ::Logger::DEBUG
         | 
| 58 | 
            +
                    ::Logger.any_instance.should_receive(:level=).with(::Logger::DEBUG)
         | 
| 59 | 
            +
                    observer.logger
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                describe "hash" do
         | 
| 64 | 
            +
                  let(:logger) { { level: ::Logger::DEBUG } }
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  it "applies options to default logger" do
         | 
| 67 | 
            +
                    observer = subject
         | 
| 68 | 
            +
                    ::Logger.any_instance.should_receive(:level=).with(::Logger::DEBUG)
         | 
| 69 | 
            +
                    observer.logger
         | 
| 70 | 
            +
                  end
         | 
| 40 71 | 
             
                end
         | 
| 41 72 | 
             
              end
         | 
| 42 73 |  | 
| @@ -14,9 +14,9 @@ shared_examples_for "a records processor" do | |
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 16 | 
             
              describe "exception handling" do
         | 
| 17 | 
            -
                 | 
| 18 | 
            -
                  let(:records) { 1..3 }
         | 
| 17 | 
            +
                let(:records) { 1..3 }
         | 
| 19 18 |  | 
| 19 | 
            +
                describe "processing a record raised StandardError" do
         | 
| 20 20 | 
             
                  it "should continue processing" do
         | 
| 21 21 | 
             
                    processor.should_receive(:process).exactly(3).times.and_raise(StandardError)
         | 
| 22 22 | 
             
                    expect { process_runner.call processor }.to_not raise_error
         | 
| @@ -35,5 +35,16 @@ shared_examples_for "a records processor" do | |
| 35 35 | 
             
                    expect { process_runner.call processor }.to raise_error(Exception)
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 | 
             
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                describe "processing a record have requested a command run" do
         | 
| 40 | 
            +
                  it "should run redo command" do
         | 
| 41 | 
            +
                    processor.should_receive(:process).with(1).once.and_raise(StandardError)
         | 
| 42 | 
            +
                    processor.should_receive(:process).with(1).once
         | 
| 43 | 
            +
                    processor.should_receive(:process).exactly(2).times
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    processor.should_receive(:record_error).once.and_throw(:command, :redo)
         | 
| 46 | 
            +
                    process_runner.call processor
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 38 49 | 
             
              end
         | 
| 39 50 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,20 +1,18 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: processor
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              version: 2.2.0
         | 
| 6 5 | 
             
            platform: ruby
         | 
| 7 6 | 
             
            authors:
         | 
| 8 7 | 
             
            - Alexander Paramonov
         | 
| 9 8 | 
             
            autorequire: 
         | 
| 10 9 | 
             
            bindir: bin
         | 
| 11 10 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date:  | 
| 11 | 
            +
            date: 2014-11-11 00:00:00.000000000 Z
         | 
| 13 12 | 
             
            dependencies:
         | 
| 14 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 14 | 
             
              name: rake
         | 
| 16 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            -
                none: false
         | 
| 18 16 | 
             
                requirements:
         | 
| 19 17 | 
             
                - - ! '>='
         | 
| 20 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -22,7 +20,6 @@ dependencies: | |
| 22 20 | 
             
              type: :development
         | 
| 23 21 | 
             
              prerelease: false
         | 
| 24 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            -
                none: false
         | 
| 26 23 | 
             
                requirements:
         | 
| 27 24 | 
             
                - - ! '>='
         | 
| 28 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -30,23 +27,20 @@ dependencies: | |
| 30 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 28 | 
             
              name: rspec
         | 
| 32 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 | 
            -
                none: false
         | 
| 34 30 | 
             
                requirements:
         | 
| 35 | 
            -
                - -  | 
| 31 | 
            +
                - - ~>
         | 
| 36 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 37 33 | 
             
                    version: '2.6'
         | 
| 38 34 | 
             
              type: :development
         | 
| 39 35 | 
             
              prerelease: false
         | 
| 40 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 41 | 
            -
                none: false
         | 
| 42 37 | 
             
                requirements:
         | 
| 43 | 
            -
                - -  | 
| 38 | 
            +
                - - ~>
         | 
| 44 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 45 40 | 
             
                    version: '2.6'
         | 
| 46 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 47 42 | 
             
              name: pry
         | 
| 48 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 | 
            -
                none: false
         | 
| 50 44 | 
             
                requirements:
         | 
| 51 45 | 
             
                - - ! '>='
         | 
| 52 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -54,7 +48,6 @@ dependencies: | |
| 54 48 | 
             
              type: :development
         | 
| 55 49 | 
             
              prerelease: false
         | 
| 56 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 | 
            -
                none: false
         | 
| 58 51 | 
             
                requirements:
         | 
| 59 52 | 
             
                - - ! '>='
         | 
| 60 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -62,7 +55,6 @@ dependencies: | |
| 62 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 63 56 | 
             
              name: pry-plus
         | 
| 64 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 65 | 
            -
                none: false
         | 
| 66 58 | 
             
                requirements:
         | 
| 67 59 | 
             
                - - ! '>='
         | 
| 68 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -70,7 +62,6 @@ dependencies: | |
| 70 62 | 
             
              type: :development
         | 
| 71 63 | 
             
              prerelease: false
         | 
| 72 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 73 | 
            -
                none: false
         | 
| 74 65 | 
             
                requirements:
         | 
| 75 66 | 
             
                - - ! '>='
         | 
| 76 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -140,35 +131,27 @@ files: | |
| 140 131 | 
             
            homepage: http://github.com/AlexParamonov/processor
         | 
| 141 132 | 
             
            licenses:
         | 
| 142 133 | 
             
            - MIT
         | 
| 134 | 
            +
            metadata: {}
         | 
| 143 135 | 
             
            post_install_message: 
         | 
| 144 136 | 
             
            rdoc_options: []
         | 
| 145 137 | 
             
            require_paths:
         | 
| 146 138 | 
             
            - lib
         | 
| 147 139 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 148 | 
            -
              none: false
         | 
| 149 140 | 
             
              requirements:
         | 
| 150 141 | 
             
              - - ! '>='
         | 
| 151 142 | 
             
                - !ruby/object:Gem::Version
         | 
| 152 143 | 
             
                  version: '0'
         | 
| 153 | 
            -
                  segments:
         | 
| 154 | 
            -
                  - 0
         | 
| 155 | 
            -
                  hash: 148591874566411659
         | 
| 156 144 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 157 | 
            -
              none: false
         | 
| 158 145 | 
             
              requirements:
         | 
| 159 146 | 
             
              - - ! '>='
         | 
| 160 147 | 
             
                - !ruby/object:Gem::Version
         | 
| 161 148 | 
             
                  version: '0'
         | 
| 162 | 
            -
                  segments:
         | 
| 163 | 
            -
                  - 0
         | 
| 164 | 
            -
                  hash: 148591874566411659
         | 
| 165 149 | 
             
            requirements: []
         | 
| 166 150 | 
             
            rubyforge_project: 
         | 
| 167 | 
            -
            rubygems_version:  | 
| 151 | 
            +
            rubygems_version: 2.2.2
         | 
| 168 152 | 
             
            signing_key: 
         | 
| 169 | 
            -
            specification_version:  | 
| 170 | 
            -
            summary: Universal processor for  | 
| 171 | 
            -
              and post processing
         | 
| 153 | 
            +
            specification_version: 4
         | 
| 154 | 
            +
            summary: Universal processor for threaded collection iteration, logging and post processing
         | 
| 172 155 | 
             
            test_files:
         | 
| 173 156 | 
             
            - spec/example_spec.rb
         | 
| 174 157 | 
             
            - spec/processor/data/array_processor_spec.rb
         |