Return Sinatra response before stopping EventMachine - sinatra

I'm using Sinatra within event-machine, and I want to shut down the server and exit upon receiving a DELETE request, and return a 200 OK. However, right now I can't get to that point, and always end u returning an empty response before exiting. How would I achieve this? Here's the relevant code:
EM.run do
class Server < Sinatra::Base
delete '*' do
EM.defer proc{ halt 200 }, proc{ EM.stop }
end
end
Server.run!
end
What happens is that I get an empty reply, and get the following stacktrace:
/Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/sinatra-1.3.3/lib/sinatra/base.rb:803:in `throw': uncaught throw `halt' in thread 0x7fa4225f2020 (ThreadError)
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/sinatra-1.3.3/lib/sinatra/base.rb:803:in `halt'
from instant-markdown-d.rb:39:in `DELETE *'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1037:in `call'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1037:in `spawn_threadpool'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1033:in `initialize'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1033:in `new'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1033:in `spawn_threadpool'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:1023:in `defer'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/thin-1.5.0/lib/thin/connection.rb:51:in `process'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/thin-1.5.0/lib/thin/connection.rb:39:in `receive_data'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run_machine'
from /Users/syeo/.rvm/gems/ruby-1.8.7-p352#instant-markdown-d/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run'
from instant-markdown-d.rb:10
I've also tried many similar ways but couldn't find a way to send a 200, then shut down the server.

Ended up doing this:
EM.run do
class Server < Sinatra::Base
delete '*' do
EM.add_timer(0.2) do
EM.stop
exit
end
status 200
end
end
Server.run!
end
Which is a hack, but at least works.

Related

Eventmachine HTTP - How to get notified if connection is lost?

I have this EM http code:
require 'eventmachine'
require 'em-http'
require 'json'
http = EM::HttpRequest.new("api_url", :keepalive => true, :connect_timeout => 0, :inactivity_timeout => 0)
EventMachine.run do
s = http.get({'accept' => 'application/json'})
s.stream do |data|
puts data
end
s.errback do
puts "FATAL EM STOPPED: #{response.error}"
EM.stop
end
end
I want to get notified if the connection is lost. I just tried to disable my WIFI and nothing is triggered. After I enable my WIFI the connection is established again and the messages are printed again. I want this behavior I just want to catch that the connection is lost, so that I can raise a error message.

How can I check the connection of Mongoid

Does Mongoid has any method like ActiveRecord::Base.connected??
I want to check if the connection that's accessible.
We wanted to implement a health check for our running Mongoid client that tells us whether the established connection is still alive. This is what we came up with:
Mongoid.default_client.database_names.present?
Basically it takes your current client and tries to query the databases on its connected server. If this server is down, you will run into a timeout, which you can catch.
My solution:
def check_mongoid_connection
mongoid_config = File.read("#{Rails.root}/config/mongoid.yml")
config = YAML.load(mongoid_config)[Rails.env].symbolize_keys
host, db_name, user_name, password = config[:host], config[:database], config[:username], config[:password]
port = config[:port] || Mongo::Connection::DEFAULT_PORT
db_connection = Mongo::Connection.new(host, port).db(db_name)
db_connection.authenticate(user_name, password) unless (user_name.nil? || password.nil?)
db_connection.collection_names
return { status: :ok }
rescue Exception => e
return { status: :error, data: { message: e.to_s } }
end
snrlx's answer is great.
I use following in my puma config file, FYI:
before_fork do
begin
# load configuration
Mongoid.load!(File.expand_path('../../mongoid.yml', __dir__), :development)
fail('Default client db check failed, is db connective?') unless Mongoid.default_client.database_names.present?
rescue => exception
# raise runtime error
fail("connect to database failed: #{exception.message}")
end
end
One thing to remind is the default server_selection_timeout is 30 seconds, which is too long for db status check at least in development, you can modify this in your mongoid.yml.

RailsTutorial: NoMethodError 'permanent' Rake::Test::CookieJar

app/helpers/sessions_helper.rb
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
end
Tests defined in section 9.2.1 Requiring signed-in users are failing:-
At first I was getting sign_in method not found then I added
include SessionsHelper
in spec/utilities.rb file after that I started getting below error, saying no method with name permanent exists in Rake::Test::CookieJar.
Is it due to some Gem version issue.
1) User Pages edit page
Failure/Error: before { sign_in user}
NoMethodError:
undefined method `permanent' for #<Rack::Test::CookieJar:0x007ff12c661e88>
# ./app/helpers/sessions_helper.rb:3:in `sign_in'
# ./spec/requests/user_pages_spec.rb:55:in `block (3 levels) in <top (required)>'
Just ran into the same problem and got it fixed.
It seems they are not referring to the sign_in method in sessions_helper.rb but the the sign_in method in spec/support/utilities.rb
In my case this helper method in utilities.rb had a different name, after renaming it everything worked fine :-)

Erlang and PostgreSQL

I try to execute simple PostgreSQL query with erlang and epgsql.
I do:
{ok, C} = pgsql:connect("localhost", "shk", "qwerty", [{database, "mydb"}]).
>> {ok,<0.34.0>}
Then:
{ok, Cols, Rows} = pgsql:squery(C, "select * from users").
But i got error:
=ERROR REPORT==== 27-Apr-2012::17:58:23 ===
** State machine <0.34.0> terminating
** Last message in was {'EXIT',<0.32.0>,
{{badmatch,
{error,
{error,'ð\236ð¨ð\230ð\221ð\232ð\220',<<"42P01">>,
<<208,190,209,130,208,189,208,190,209,136,208,181,
208,189,208,184,208,181,32,34,109,121,100,98,34,
32,208,189,208,181,32,209,129,209,131,209,137,
208,181,209,129,209,130,208,178,209,131,208,181,
209,130>>,
[{position,<<"15">>}]}}},
[{erl_eval,expr,3}]}}
** When State == ready
** Data == {state,undefined,<0.35.0>,5000,
[{<<"application_name">>,<<>>},
{<<"client_encoding">>,<<"UTF8">>},
{<<"DateStyle">>,<<"ISO, DMY">>},
{<<"integer_datetimes">>,<<"on">>},
{<<"IntervalStyle">>,<<"postgres">>},
{<<"is_superuser">>,<<"off">>},
{<<"server_encoding">>,<<"UTF8">>},
{<<"server_version">>,<<"9.0.7">>},
{<<"session_authorization">>,<<"shk">>},
{<<"standard_conforming_strings">>,<<"off">>},
{<<"TimeZone">>,<<"posixrules">>}],
undefined,undefined,undefined,
{30932,488494147},
{statement,undefined,undefined,undefined},
73}
** Reason for termination =
** {{badmatch,{error,{error,'ð\236ð¨ð\230ð\221ð\232ð\220',<<"42P01">>,
<<208,190,209,130,208,189,208,190,209,136,208,181,
208,189,208,184,208,181,32,34,109,121,100,98,34,
32,208,189,208,181,32,209,129,209,131,209,137,
208,181,209,129,209,130,208,178,209,131,208,181,
209,130>>,
[{position,<<"15">>}]}}},
[{erl_eval,expr,3}]}
What's wrong i do? How can i fix it?
Thank you.
The error string seems to be in russian if I recognize the characters.
To view the response you can use the following command:
io:format("~ts",[<<208,190,209,130,208,189,208,190,209,136,208,181,
208,189,208,184,208,181,32,34,109,121,100,98,34,
32,208,189,208,181,32,209,129,209,131,209,137,
208,181,209,129,209,130,208,178,209,131,208,181,
209,130>>]).
отношение "mydb" не существует
A quick google translate makes me think the database mydb does not exist or you do not have permissions to use it.
try simply doing
Response = pgsql:squery(C, "select * from mydb"),
io:format("~p~n",[Response]).
And see what he is giving back from the server, maybe you have typo or table don't exists etc.
also check this out http://www.erlangatwork.com/2009/01/erlang-and-postgresql.html
From epgsql docs:
Errors
Errors originating from the PostgreSQL backend are returned as {error, #error{}},
see pgsql.hrl for the record definition. epgsql functions may also return
{error, What} where What is one of the following:
{unsupported_auth_method, Method} - required auth method is unsupported
timeout - request timed out
closed - connection was closed
sync_required - error occured and pgsql:sync must be called
Try to include pgsql.hrl, capture the error and print the error message, that should point you to the right direction.

MMS2R and Multiple Images Rails

Here's my code:
require 'mms2r'
class IncomingMailHandler < ActionMailer::Base
##
# Receives email(s) from MMS-Email or regular email and
# uploads that content the user's photos.
# TODO: Use beanstalkd for background queueing and processing.
def receive(email)
begin
mms = MMS2R::Media.new(email)
##
# Ok to find user by email as long as activate upon registration.
# Remember to make UI option that users can opt out of registration
# and either not send emails or send them to a username+32523#example.com
# type address.
##
# Remember to get SpamAssasin
if (#user = User.find_by_email(email.from) && email.has_attachments?)
mms.media.each do |key, value|
if key.include?('image')
value.each do |file|
#user.photos.push Photo.create!(:uploaded_data => File.open(file), :title => email.subject.empty? ? "Untitled" : email.subject)
end
end
end
end
ensure
mms.purge
end
end
end
and here's my error:
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/commands/runner.rb:48: undefined method `photos' for true:TrueClass (NoMethodError)
from /usr/home/xxx/app/models/incoming_mail_handler.rb:23:in `each'
from /usr/home/xxx/app/models/incoming_mail_handler.rb:23:in `receive'
from /usr/home/xxx/app/models/incoming_mail_handler.rb:21:in `each'
from /usr/home/xxx/app/models/incoming_mail_handler.rb:21:in `receive'
from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:419:in `receive'
from (eval):1
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `eval'
from /usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/commands/runner.rb:48
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /home/xxx/script/runner:3
I sent an email to the server with two image attachments. Upon receiving the email the server runs
"| ruby /xxx/script/runner 'IncomingMailHandler.receive STDIN.read'"
What is going on? What am I doing wrong?
(MMS2R docs)
Please replace
if (#user = User.find_by_email(email.from) && email.has_attachments?)
with
if ((#user = User.find_by_email(email.from)) && email.has_attachments?)