Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenSSL::Cipher::CipherError under high concurrent load. #372

Open
omaik opened this issue Jun 18, 2020 · 2 comments
Open

OpenSSL::Cipher::CipherError under high concurrent load. #372

omaik opened this issue Jun 18, 2020 · 2 comments

Comments

@omaik
Copy link

omaik commented Jun 18, 2020

Hey there!

Having the following exception on a random basis

OpenSSL::Cipher::CipherError: null
  from encryptor.rb:98:in `final'
  from encryptor.rb:98:in `crypt'
  from encryptor.rb:49:in `decrypt'
  from attr_encrypted.rb:240:in `decrypt'
  from attr_encrypted.rb:329:in `decrypt'
  from attr_encrypted.rb:161:in `block (2 levels) in attr_encrypted'

Steps to Reproduce

  1. gem version
    attr_encrypted (3.1.0)
      encryptor (~> 3.0.0)
  1. model
class Customer < ApplicationRecord
  ...
  attr_encrypted :ssn, key: Settings.data_encryption.encryption_key
  ...
end
  1. test sidekiq worker
class ConcurrencyWorker
  include Sidekiq::Worker

  def perform
    customer = Customer.last
    customer.assign_attributes(ssn: SecureRandom.hex)
  end
end
  1. start sidekiq with 60 threads
bundle exec sidekiq -c 60
  1. from Rails Console
> loop { ConcurrencyWorker.perform_async }

You will see the exception above once per 3-5 minutes.

Additional details(may give a clue)

Played with retrying this error

The following approach Does not work, every consequent retry fails with the same error.

class ConcurrencyWorker
  include Sidekiq::Worker

  def perform
    customer = Customer.last
    begin
      retry_count ||= 0
      customer.assign_attributes(ssn: SecureRandom.hex)
    rescue OpenSSL::Cipher::CipherError => e
      retry_count += 1
      Sidekiq.logger.info('Retrying')
      raise e if retry_count > 3

      retry
    end
  end
end

The following approach Does work. The job succeeds after the first retry.

class ConcurrencyWorker
  include Sidekiq::Worker

  def perform
    retry_count ||= 0
    customer = Customer.last
    customer.assign_attributes(ssn: SecureRandom.hex)
  rescue OpenSSL::Cipher::CipherError => e
    retry_count += 1
    Sidekiq.logger.info('Retrying')
    raise e if retry_count > 3

    retry
  end
end

That gives the assumption that state corruption happens on an individual ActiveRecord object level.

The issue seems to be reproducible only in a multithreaded environment under high load.

Thanks in advance for any help provided :)

@bblack
Copy link

bblack commented Apr 23, 2021

d4ca0e2 fixed this for me.

@jpcamara
Copy link

d4ca0e2 fixed this for me.

Fixed it for me as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants