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?)