简体   繁体   中英

Sidekiq worker not able to write to database or log file

I'm building an app on Herokou and Redis that sends an SMS messages for every row in an input CSV file which contains the mobile phone number. The message is sent using Twilio in a sidekiq worker shown below. The problem is that even though the SMS is being sent for all the rows in the CSV, the database write ( TextMessage.create) and log write ( puts statement) only executes for one row in the CSV. There is one Sidekiq worker spawned for each row in the CSV file. It seems like only one Sidekiq worker has I/O (DB, file) access and it locks it from the other Sidekiq workers. Any help would be appreciated.

sidekiq worker:

require 'sidekiq'
require 'twilio-rb'

class TextMessage < ActiveRecord::Base
    include Sidekiq::Extensions

    def self.send_message(number, body, row_index, column_index, table_id)
        puts "TextMessage#send_message: ROW INDEX: #{row_index} COLUMN INDEX: #{column_index} TABLEID: #{table_id} BODY: #{body} PHONE: #{number}"

        Twilio::Config.setup :account_sid  => 'obfuscated', :auth_token   => '<obfuscated>'
    sms = Twilio::SMS.create :to => number, :from => '+17085555555', :body => body +  ' | Sent: ' + Time.now.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central")
        TextMessage.create :to => number, :from => '+17085555555'
        ImportCell.add_new_column(table_id, row_index, column_index, "Time Sent", Time.now.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central"))
    end
end

call to sidekiq worker:

 TextMessage.delay_until(time_to_send, :retry => 3).send_message(phone, 'Scheduled: ' + time_to_send.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central"), row_index, column_index, table.id)
      column_index += 1  

Heroku Procfile

worker: bundle exec sidekiq -C config/sidekiq.yml

sidekiq.yml

:verbose: false
:concurrency:  3
:queues:
  - [default, 5]

config/initializers/redis.rb :

uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)

Sidekiq.configure_server do |config|
 database_url = ENV['DATABASE_URL']
 if(database_url)
   ENV['DATABASE_URL'] = "#{database_url}?pool=25"
   ActiveRecord::Base.establish_connection
  end
end

I am one of the people who commented on your question, just fixed it!

You are using .create which SideKiq seemed to not like, so I tried using .new and then .save which made it work! I think it has to do with .create not being thread safe or something of the sort, but I honestly have no idea.

Non Working code:

class HardWorker
    include Sidekiq::Worker

    def perform(name, count)
        puts 'Doing some hard work!'

        UserInfo.create(
         :user => "someone",
         :misc1 => 0,
         :misc2 => 0,
         :misc3 => 0,
         :comment => "Made from HardWorker",
         :time_changed => Time.now
        )

        puts 'Done with hard work!'
    end
end

Working code:

class HardWorker
    include Sidekiq::Worker

    def perform(name, count)
        puts 'Doing some hard work!'

        a_row = UserInfo.new(
         :user => "someone",
         :misc1 => 0,
         :misc2 => 0,
         :misc3 => 0,
         :comment => "Made from HardWorker",
         :time_changed => Time.now
        )

        a_row.save

        puts 'Done with hard work!'
    end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM