Sidekiq - Sinatra - Can't read from my ActiveRecord Objects - ruby

For some reason, my sidekiq worker can't read from my ActiveRecord models. Here is my worker class. It fails on line where its trying to read from my User object: name = User.find_by(id: user_id).first_name.
require 'gcm'
module Socio
class RequestNotificationWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(target_token, key)
begin
gcm = GCM.new(key)
registration_ids= [target_token]
options = {notification: {title: "Connection request!", body: "You have a new Socio request.",
sound: "default", badge: 1, type: "1"},
collapse_key: "New Connections", content_available: true, priority: "high"}
gcm.send(registration_ids, options)
{success: true}
rescue => e
{success: false, error: e.to_s}
end
end
end
class ConfirmNotificationWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(target_token, key)
begin
gcm = GCM.new(key)
name = User.find_by(id: #user_id).first_name
registration_ids= [target_token]
options = {notification: {title: "Connection Confirmed!", body: "#{name} has accepted your Socio request.",
sound: "default", badge: 1, type: "2"},
collapse_key: "New Connections", content_available: true, priority: "high"}
gcm.send(registration_ids, options)
{success: true}.to_json
rescue => e
{success: false, error: e.to_s}
end
end
end
end
Also here is my procfile:
web: bundle exec thin start -p $PORT
worker: bundle exec sidekiq -c 5 -v -r ./app/sidekiq.rb
And here is the error message:
Failed uninitialized constant Socio::ConfirmNotificationWorker::User
I tried different require and include commands, but couldn't get it to work.

Somewhere inside app/sidekiq.rb you need to require activerecord and user.rb. If you show us your sidekiq.rb it will help.

This is because app/sidekiq is not initializing your application - you have probably all relevant require statements in the main application file (app.rb). Compare app/sidekiq.rb with app.rb file (and possible other files in the tree) and add relevant require instructions in the first one.
You can also start the console session (for example using Pry: pry -r ./app/sidekiq.rb or built-in irb: irb -r ./app/sidekiq.rb) with app/sidekiq and check if all needed classes are there or even better: write specs to check if it works fine.

Related

Why is server.rb throwing this error in terminal

I am following along with this stripe tutorial but the server.rb in the example from Stripe's Github is throwing an error when I run Ruby server.rb
I am very new to ruby so I could be doing things wrong.
What I did was:
Installed Ruby, Rails, Stripe CLI, Sinatra, and dotenv
Downloaded the example from the site by typing Stripe samples create
developer-office-hours
cd'd into the server directory and ran ruby
server.rb
this is the error
1: from server.rb:10:in '<main.'
server.rb:10:in 'join': no implicit conversation of nil into string (TypeError)
here is the server.rb file
require 'stripe'
require 'sinatra'
require 'dotenv'
# Replace if using a different env file or config
Dotenv.load
Stripe.api_key = ENV['STRIPE_SECRET_KEY']
set :static, true
set :public_folder, File.join(File.dirname(__FILE__), ENV['STATIC_DIR'])
set :views, File.join(File.dirname(__FILE__), ENV['STATIC_DIR'])
set :port, 4242
get '/' do
content_type 'text/html'
send_file File.join(settings.public_folder, 'index.html')
end
post '/webhook' do
# You can use webhooks to receive information about asynchronous payment events.
# For more about our webhook events check out https://stripe.com/docs/webhooks.
webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
payload = request.body.read
if !webhook_secret.empty?
# Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
event = nil
begin
event = Stripe::Webhook.construct_event(
payload, sig_header, webhook_secret
)
rescue JSON::ParserError => e
# Invalid payload
status 400
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
puts "⚠️ Webhook signature verification failed."
status 400
return
end
else
data = JSON.parse(payload, symbolize_names: true)
event = Stripe::Event.construct_from(data)
end
# Get the type of webhook event sent - used to check the status of PaymentIntents.
event_type = event['type']
data = event['data']
data_object = data['object']
if event_type == 'some.event'
puts "🔔 Webhook received!"
end
content_type 'application/json'
{
status: 'success'
}.to_json
end
stripe login
This is a crucial step.
stripe samples create adding-sales-tax
cd adding-sales-tax/server
bundle install
If you don't have bundler, gem install bundler
bundle exec ruby server.rb
Open http://localhost:4242

Newly created sidekiq worker not found (NameError: uninitialized constant UniqueJobWorkerTest::UniqueJobWorker)

unique_job_worker.rb
# -*- encoding : utf-8 -*-
require_relative 'logging_helper'
class UniqueJobWorker
include Sidekiq::Worker
include WorkerHelper
sidekiq_options retry: false,
backtrace: true,
queue: :sender,
failures: true
def perform(worker,campaign_guid, queue)
require'pry';binding.pry
end
end
unique_job_worker_test.rb
require 'test_helper'
require 'mocha/setup'
class UniqueJobWorkerTest < ActiveSupport::TestCase
def setup
require'pry';binding.pry
#worker = UniqueJobWorker.new
end
test "it exists" do
assert #worker
end
end
When enqueued through redis I get this response
INFO -- : Exception: uninitialized constant UniqueJobWorker
Any suggestions as to why my newly created worker, UniqueJobWorker, is not being found during runtime through redis or through a simple test?
Thanks ahead of time!
When you use sidekiq outside of Rails, you need to use the -r option to tell it how to load your workers. So (assuming that your worker is in a sub-directory called workers):
% sidekiq -r ./workers/unique_job_worker.rb
If you have multiple workers, an option is to create a loader file to ensure everything is loaded.
load_workers.rb
($LOAD_PATH << 'workers').uniq!
require 'unique_job_worker'
require 'other_worker'
...
Then require the loader file on the command line:
% sidekiq -r ./load_workers.rb
I had the same issue and ended up being a Redis namespace issue:
https://github.com/mperham/sidekiq/issues/2834#issuecomment-184800981
Adding that fixed it for me:
config.redis = {
url: ENV['REDIS_URL'],
namespace: "some_namespace_different_for_each_app"
}
You also need the redis-namespace gem BTW

Using env with rack_test

In a Rails app, I have the following configuration to run System Rspec specs.
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
end
config.before(:each, type: :system, js: true) do
driven_by :selenium, using: :headless_chrome, screen_size: [1300, 1240]
end
end
Now, I have added a middleware that depends upon env['REQUEST_PATH'] and, when I run the specs using rack_test I get
Failure/Error: _, id, request_path = env['REQUEST_PATH'].split('/', 3)
NoMethodError: undefined method `split' for nil:NilClass
However, if I always use selenium, all the specs pass like before.
Is there a way to use/set env['REQUEST_PATH'] with rack_test?

Rake: ArgumentError: unknown keywords: when passing method parameters

I'm working on a pure Ruby application where I'm trying to create a Rake task. I have a method in the file src/lambda_function.rb that is as follows:
def self.process(event:, context: nil, box_api: BoxApi.new, form: nil, sns: SNS.new, kms: KMS.new)
begin
# verify request came from fromstack from headers
verify_webhook_req(event)
# parse data
submission = JSON.parse(event["body"])
form_id = submission.fetch("FormID").strip()
submission_id = submission.fetch("UniqueID").strip()
As you can see from the above snippet the function takes in the following parameters:
event:, context:, box_api:, form:, sns:, kms: So in the rake task I pass the following:
require './src/lambda_function.rb'
require 'rake'
require 'pry'
include Rake::DSL
class KMS
def initialize
end
def decrypt(key)
return 'some password'
end
end
class SNS
def initialize
end
end
namespace :test do
namespace :lambda do
desc 'Run the Lambda process function'
task :process do
TEST_FORM_ID=3353951
LambdaFunctions::LambdaHandler.process(box_api: BoxApi.new,
form: TEST_FORM_ID,
sns: SNS.new,
kms: KMS.new)
end
end
end
But calling this rake task throws an error:
rake aborted!
ArgumentError: unknown keywords: box_api, form
How come it doesn't recognize form and box_api. At first, I thought that maybe I was missing a hash to pass in the arguments. {box_api: BoxApi.new, form: ....}` this didn't work either.
Why is throwing the error?
I was calling a method in a different class which had different parameters.
class WebhookHandler
def self.process(event:, context: nil, box_api: BoxApi.new, form: nil, sns: SNS.new, kms: KMS.new)
begin
# verify request came from fromstack from headers
verify_webhook_req(event)

Daemonizing Mailman app

Starting my mailman app by running rails runner lib/daemons/mailman_server.rb works fine.
When starting with my daemon script and command bundle exec rails runner script/daemon run mailman_server.rb, the script generates an error:
.rvm/gems/ruby-1.9.3-p194/gems/mailman-0.5.3/lib/mailman/route/conditions.rb:21:in `match': undefined method `each' for nil:NilClass (NoMethodError)
My code is as follows:
lib/daemons/mailman_server.rb
require 'mailman'
# Config Mailman
Mailman.config.ignore_stdin = false
Mailman.config.graceful_death = true
Mailman.config.poll_interval = 15
Mailman.config.logger = Logger.new File.expand_path("../../../log/mailman.log", __FILE__)
Mailman.config.pop3 = {
:username => 'alias#mygoogleapp.com',
:password => 'password',
:server => 'pop.gmail.com',
:port => 995,
:ssl => true
}
# Run the mailman
Mailman::Application.run do
from('%email%').to('alias+q%id%#mygoogleapp.com') do |email, id|
begin
# Get message without headers to pass to add_answer_from_email
if message.multipart?
reply = message.text_part.body.decoded
else
reply = message.body.decoded
end
# Call upon the question to add answer to his set
Question.find(id).add_answer_from_email(email, reply)
rescue Exception => e
Mailman.logger.error "Exception occured while receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
and my script/daemon file is:
#!/usr/bin/env ruby
require 'rubygems'
require "bundler/setup"
require 'daemons'
ENV["APP_ROOT"] ||= File.expand_path("#{File.dirname(__FILE__)}/..")
script = "#{ENV["APP_ROOT"]}/lib/daemons/#{ARGV[1]}"
Daemons.run(script, dir_mode: :normal, dir: "#{ENV["APP_ROOT"]}/tmp/pids")
Any insight as to why it fails as a daemon?

Resources