Chewy, RSpec и Threads поднимают странную ошибку - PullRequest
0 голосов
/ 20 ноября 2018

Я тестирую некоторые параллельные поведения, используя RSpec, и возникает странное исключение.

expect{
  threads = 4.times.map do
    Thread.new do
      WebMock.allow_net_connect!
      PaymentForm.new(params).process
    end
  end

  threads.each(&:join)
}.to change{
  Payment.count
}.by(1)

После вызова метода PaymentForm#process создается запись Payment (модель).Модель Payment индексируется с помощью Chewy в ElasticSearch, обновляя индекс сразу после сохранения модели.

Оказывается, возникает странное исключение:

  1) Checkout::PaymentForm#process when the payment is duplicated blocks repeated transactions
     Failure/Error: unless save

     NoMethodError:
       undefined method `get' for nil:NilClass
       Did you mean?  gem
     # /usr/local/bundle/gems/httpclient-2.8.3/lib/httpclient/session.rb:726:in `set_header'
     # /usr/local/bundle/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:206:in `headers_from_session'
     # /usr/local/bundle/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:168:in `build_request_signature'
     # /usr/local/bundle/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:55:in `do_get'
     # /usr/local/bundle/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:47:in `do_get_block'
     # /usr/local/bundle/gems/httpclient-2.8.3/lib/httpclient.rb:1019:in `block in do_request'
     # /usr/local/bundle/gems/httpclient-2.8.3/lib/httpclient.rb:1133:in `protect_keep_alive_disconnected'
     # /usr/local/bundle/gems/httpclient-2.8.3/lib/httpclient.rb:1014:in `do_request'
     # /usr/local/bundle/gems/httpclient-2.8.3/lib/httpclient.rb:856:in `request'
     # /usr/local/bundle/gems/faraday-0.15.2/lib/faraday/adapter/httpclient.rb:38:in `call'
     # /usr/local/bundle/gems/faraday-0.15.2/lib/faraday/rack_builder.rb:143:in `build_response'
     # /usr/local/bundle/gems/faraday-0.15.2/lib/faraday/connection.rb:387:in `run_request'
     # /usr/local/bundle/gems/elasticsearch-transport-6.1.0/lib/elasticsearch/transport/transport/http/faraday.rb:23:in `block in perform_request'
     # /usr/local/bundle/gems/elasticsearch-transport-6.1.0/lib/elasticsearch/transport/transport/base.rb:266:in `perform_request'
     # /usr/local/bundle/gems/elasticsearch-transport-6.1.0/lib/elasticsearch/transport/transport/http/faraday.rb:20:in `perform_request'
     # /usr/local/bundle/gems/elasticsearch-transport-6.1.0/lib/elasticsearch/transport/client.rb:131:in `perform_request'
     # /usr/local/bundle/gems/elasticsearch-api-6.1.0/lib/elasticsearch/api/namespace/common.rb:21:in `perform_request'
     # /usr/local/bundle/gems/elasticsearch-api-6.1.0/lib/elasticsearch/api/actions/indices/exists.rb:46:in `block in exists'
     # /usr/local/bundle/gems/elasticsearch-api-6.1.0/lib/elasticsearch/api/utils.rb:202:in `__rescue_from_not_found'
     # /usr/local/bundle/gems/elasticsearch-api-6.1.0/lib/elasticsearch/api/actions/indices/exists.rb:45:in `exists'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/index/actions.rb:15:in `exists?'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/type/import/routine.rb:69:in `create_indexes!'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/type/import.rb:131:in `import_routine'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/type/import.rb:87:in `import!'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/strategy/urgent.rb:13:in `update'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/type/observe.rb:76:in `update_index'
     # /usr/local/bundle/gems/chewy-5.0.0/lib/chewy/type/observe.rb:34:in `block in update_proc'
     # /usr/local/bundle/gems/bugsnag-6.7.0/lib/bugsnag/integrations/rails/active_record_rescue.rb:25:in `run_callbacks'
     # /usr/local/bundle/gems/airbrake-6.2.1/lib/airbrake/rails/active_record.rb:22:in `run_callbacks'
     # ./app/models/payment.rb:176:in `update_with_payment_response_data'
     # ./app/models/checkout/payment_form.rb:93:in `block in process'
     # ./lib/record_lock.rb:34:in `with_lock'
     # ./lib/record_lock.rb:27:in `with_lock'
     # ./app/models/checkout/payment_form.rb:72:in `process'
     # ./spec/models/checkout/payment_form_spec.rb:532:in `block (7 levels) in <main>'

Из того, что яможет отладить, исключение происходит, когда Чуви пытается обновить индекс с помощью HTTP-клиента Фарадея.

Я также использую WebMock, но я вызываю WebMock.allow_net_connect! для каждого потока, что делает его разрешающим.Обратите внимание, что это происходит только тогда, когда я использую темы.Без потоков работает нормально.

...