"PGError: no connection to the server" while trying to create or save - ruby

Ruby 1.9.1 + ActiveRecord 2.3.5 + Postgres 8.3.7
Here is a rough sketch of my code. Ignore any obvious syntax details left out. The model below inherits from ActiveRecord::Base connected to a Postgres 8.3.7 database via ActiveRecord 2.3.5.
class TableA
has_many :tableB
end
class TableB
belongs_to :tableA
has_many :tableC
end
class TableC
belongs_to :tableB
has_many :tableD
end
class TableD
belongs_to :tableC
has_many :tableE
end
class TableE
belongs_to :tableD
end
# Note that tableA has fids that are referenced in tableE but is not part of this model
#
# Later in the script, in the same global scope, I want to add entries to these tables if
# I cannot find what I need. Bear in mind that this part betrays much Ruby noobiness.
toAdd.each do |widget|
add_tableA = TableA.find_by_sql().first # assumes I will get one back based on earlier sanity checks
add_tableB = TableB.find_by_sql().first
if (add_tableB == nil)
new_tableB = TableB.new( # value assignments )
new_tableB.save
add_tableB = TableB.find_by_sql().first
end
add_tableC = TableC.find_by_sql().first
if (add_tableC == nil)
new_tableC = TableC.new( # value assignments )
new_tableC.save
add_tableC = TableC.find_by_sql().first
end
add_tableD = TableD.find_by_sql().first
if (add_tableD == nil)
new_tableD = TableD.new( # value assignments )
new_tableD.save
add_tableD = TableD.find_by_sql().first
end
# I step into TableA again because items in TableE are linked to items in TableA, but they are
# distinct from the "high level" item I grabbed from TableA earlier.
add_tableA = TableA.find_by_sql().first
if (add_tableA == nil)
new_tableA = TableA.new( # value assignments )
new_tableA.save
add_tableA = TableA.find_by_sql().first
end
# Now that I have a TableA id to put into TableE, just create TableE row because I know this
# does not exist yet.
new_tableE = TableE.new( # value assignments ) # again, this is assumed to be new based on earlier checks
new_tableE.save
end
What always happens is I get the following stack trace:
/...gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `rescue in log': PGError: no connection to the server (ActiveRecord::StatementInvalid)
: ROLLBACK
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `log'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/postgresql_adapter.rb:550:in `execute'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/postgresql_adapter.rb:576:in `rollback_db_transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:143:in `rescue in transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:125:in `transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `block in save_with_transactions!'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from .../gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save_with_transactions!'
.... regardless if I'm calling save, save!, or doing a create instead of new and save.
strace reveals that I can only get one BEGIN..INSERT..COMMIT transaction to work for each run of this. Any subsequent attempts to INSERT within a transaction either in the same run of the loop or the next one ends with the connection being dropped before a COMMIT is sent. Clearly, I'm doing something wrong here with how I'm stepping into the ActiveRecord model.
I see the following strace only just before the first successful INSERT statement is set up. Is there something in ActiveRecord that allows me to preserve this as I step through tables, or am I simply Doing It Wrong?
rt_sigaction(SIGPIPE, {0x1, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, {0x4b2ff0, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, 8) = 0
sendto(3, "Q\0\0\2e SELECT attr.attna"..., 614, 0, NULL, 0) = 614
rt_sigaction(SIGPIPE, {0x4b2ff0, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, {0x1, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, 8) = 0
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "T\0\0\0:\0\2attname\0\0\0\4\341\0\2\0\0\0\23\0#\377\377\377\377\0"..., 16384, 0, NULL, NULL) = 541
Any help here is greatly appreciated.

Thanks everyone. I apologize for taking anyone's time in trying to fix this. This instance of postgres depends upon a second process to run to handle pushing trigger events out to other processes. That process was not running, so the database server booted after the first committed INSERT. It's a custom in-house kind of thing.

Related

How to refactor on easy way simple rspec test to use subject/let/it and FactoryGirl?

Basically i am having very simple test where i check if account_id from Grant (so id of his parent) is equal to account_id of Role model.
Test seems ok, but i need to refactor it to use subject/let and to use FactoryGirl and i can't do that even with all the info on this subject i found.
So, test is fine i just need help with refactoring.
It's first time for me working with rails and writing test on it, so i am forced to ask this type of question here.
describe "validations" do
it "should have equal account_id" do
first_acc, second_acc = Account.new, Account.new
first_acc.id, second_acc.id = 10, 11
vlada_role, vlada_grant = Role.new, Grant.new
vlada_role1, vlada_grant1 = Role.new, Grant.new
vlada_role.account_id = first_acc.id
vlada_grant.account_id = second_acc.id
vlada_role.id, vlada_grant.id = 8000, 255
rg = RoleGrant.new
rg1 = RoleGrant.new
rg.role, rg1.role = vlada_role, vlada_role1
rg.grant, rg1.grant = vlada_grant, vlada_grant1
expect(rg.role.account_id).not_to eql(rg.grant.account_id)
expect(rg1.role.account_id).to eql(rg1.grant.account_id)
end
end

Insert into select with a hard coded value with Ruby Sequel

I am using Ruby Sequel to move data into reporting tables daily. I am consolidating data from three tables into a single table. I am doing this in Redshift so I have to use disable_insert_returning. The names of the columns in the two tables match each other but not the end table which means I am using graph and set_graph_aliases.
reports = db[:reports]
report_columns = [:user_id, :purchase_date, :sku]
spoons_select_graph = {
user_id: :users,
purchase_date: :spoon_receipts,
product_id: :spoon_receipts
}
spoons = db[:spoon_receipts]
spoons_select = spoons.graph(:users, user_id: :user_id).set_graph_aliases(spoons_select_graph)
forks_select_graph = {
user_id: :users,
purchase_date: :fork_receipts,
product_id: :fork_receipts
}
forks = db[:fork_receipts]
forks_select = forks.graph(:users, user_id: :user_id).set_graph_aliases(forks_select_graph)
reports.disable_insert_returning.insert(report_columns, spoons_select)
reports.where(channel: nil).update(channel: 'spoons')
reports.disable_insert_returning.insert(report_columns, forks_select)
reports.where(channel: nil).update(channel: 'forks')
The updates are taking forever. What I would like to do is add the channel to the insert select so that I don't have to go back and update.
You didn't provide an executable setup, so I haven't tested this, but I think it will work. The basic idea is to just add a constant column of results to your select.
reports = db[:reports]
report_columns = [:user_id, :purchase_date, :sku, :channel]
spoons_select_graph = {
user_id: :users,
purchase_date: :spoon_receipts,
product_id: :spoon_receipts,
channel: [:spoon_receipts, :channel, 'spoons']
}
spoons = db[:spoon_receipts]
spoons_select = spoons.graph(:users, user_id: :user_id).set_graph_aliases(spoons_select_graph)
reports.disable_insert_returning.insert(report_columns, spoons_select)
See the documentation for set_graph_aliases for more information.

how to exclude from counting holidays in rails4

I am trying to make an app for vacation requests but i am facing a problem.I have e model called VacationRequest and a view of VacationRequest where the result will be shown.
VacationRequest.rb model
def skip_holidays
count1 = 0
special_days = Date.parse("2017-05-09", "2017-05-12")
special_days.each do |sd|
if ((start_data..end_data) === sd)
numero = (end_data - start_data).to_i
numro1 = numero - sd
else
numero = (end_data - start_data).to_i
end
end
end
VacationRequest show.htm.erb
here i called the method from model
#vacation_request.skip_holidays
this is showing errors and is not working. Please help me with that!
My approach to this would be the following:
def skip_holidays
special_days = ["2017-05-09", "2017-05-12"].map(&:to_date)
accepted_days = []
refused_days = []
(start_data..end_data).each do |requested_date|
accepted_days << requested_date unless special_days.include?(requested_date)
refused_days << requested_date if special_days.include?(requested_date)
end
accepted_day_count = accepted_days.count
refused_days_count = refused_days.count
end
This way you iterated over all requested dates (the range), checked if the date is a special day - If so, refuse it, otherwise accept it.
In the end you can display statistics about accepted and refused dates.
You cannot create a date range by passing multiple argument to the constructor. Instead call the constructor twice to create a range:
special_days = Date.parse("2017-05-09") .. Date.parse("2017-05-12")
Or if instead you want only the two dates, do:
special_days = ["2017-05-09", "2017-05-12"].map &:to_date
This Date.parse("2017-05-09", "2017-05-12") don`t create a range, only return the first params parsed:
#irb
Date.parse("2017-05-09", "2017-05-12")
=> Tue, 09 May 2017
You can do it this way:
initial = Date.parse("2017-05-09")
final = Date.parse("2017-05-12")
((initial)..final).each do |date|
#rules here.
end

SoftLayer API call getVirtualGuests is significantly slower than in the past

I have a basic ruby program I've been using for several months now that retrieves hardware and virtualguest machine details for my account. Up until roughly 3 days ago this always ran fine and relatively fast. Since then it often crashes and/or the virtualguest retrieval takes 20-30 times longer than it has in the past. What could be the issue here? The crash stack is not very informative of the problem.
Program:
require 'rubygems'
require 'softlayer_api'
require 'pp'
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
account = client['Account'].object_mask("mask[virtualGuestCount,hardwareCount]").getObject()
virtual_machines_count = account["virtualGuestCount"]
bare_metal_machines_count = account["hardwareCount"]
bare_metal_machines_count_index = 0
virtual_machines_count_index = 0
for i in 0..(bare_metal_machines_count/10.0).ceil - 1
list_of_baremetal_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getHardware
for x in 0..list_of_baremetal_machines.length - 1
bare_metal_machines_count_index = bare_metal_machines_count_index + 1
if bare_metal_machines_count_index == bare_metal_machines_count
pp("Finished retrieving " + bare_metal_machines_count.to_s + " bare metal machines")
end
end
end
for i in 0..(virtual_machines_count/10.0).ceil - 1
list_of_virtual_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getVirtualGuests
for x in 0..list_of_virtual_machines.length - 1
virtual_machines_count_index = virtual_machines_count_index + 1
if virtual_machines_count_index == virtual_machines_count
pp("Finished retrieving " + virtual_machines_count.to_s + " virtual machines")
end
end
end
The crash looks like (the process.rb line 552 contains the getVirtualGuests call):
/opt/cds/ruby/lib/ruby/2.1.0/xmlrpc/client.rb:271:in `call': An error has occurred while processing your request. Please try again later. (XMLRPC::FaultException)
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/Service.rb:267:in `call_softlayer_api_with_params'
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/APIParameterFilter.rb:194:in `method_missing'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:552:in `block (5 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each_with_time_with_zone'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:551:in `block (4 levels) in retrieve_softlayer_inventory_information'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `each'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `block (3 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `call'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `block in spawn_threadpool'
Thank you in advance for any help.
The cause of this exception could be due to the amount of data that is attempting to be retrieved at once.
As first suggestion I would tell you, that you use “result limits” in your script. But I can see that you are using this. In that case, you may reduce the values of your result limits.
Other reason could be the query generated from that “object masks” is too intensive and is causing the failures. In that case it is recommended that you please reduce the values in the “object masks”, maybe splitting the retrieval of all those properties into multiple calls and additionally adding a cool down period in the iteration of their virtual guests.
This is pseudo code what I trying to explain:
for x in myVsis:
vsiId = myVsis.id
tempVsiObject1 = getVsi('[property1,property2, property3, property4]') // Call 1 with reduced properties in the mask
tempVsiObject2 = getVsi('[property5, property6, property7 ]') // Call 2 with reduced properties in the mask
tempVsiObject3 = getVsi('[property8[property9[property10[property11]]]]') // Call 3 with reduced properties in the mask
vsi = merge_objects(tempVsiObject1, tempVsiObject2, tempVsiObject3)
sleep(1) // cool down 1 second before moving to the next VSI
I hope this alternative help you, where the result will have in lighter queries each time.

How to organize default order in pagination?

I use will_paginate with ajax sort and seen railscasts.com.
http://railscasts.com/episodes/240-search-sort-paginate-with-ajax
My collection for pagination
#cars = Car.joins(:engine).includes(:engine).select('cars.*, engines.*').order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 5)
But when I went to the index page, I jumped out error.
ActiveRecord::StatementInvalid in Items#index
SQLite3::SQLException: ambiguous column name: name: SELECT "cars"."id" AS t0_r0, "cars"."name" AS t0_r1, "cars"."model_id" AS t0_r2, "cars"."city_id" AS t0_r3, "cars"."created_at" AS t0_r4, "cars"."updated_at" AS t0_r5, "cars"."engine_id" AS t0_r6, "engines"."id" AS t1_r0, "engines"."name" AS t1_r1, "engines"."created_at" AS t1_r2, "engines"."updated_at" AS t1_r3 FROM "cars" INNER JOIN "engines" ON "engines"."id" = "cars"."engine_id" ORDER BY name asc LIMIT 5 OFFSET 0
But when I go to a page already sorted, it works for me.
I think mistake in default Order in SQL.
How to set 'cars.name' instead 'name'?
I found method and set sort default
private
def sort_column
Car.column_names.include?(params[:sort]) ? params[:sort] : "cars.name"
end

Resources