Open abMatGit opened 7 years ago
I am running into a similar issue with rake db:reset
in development mode, where we are trying to use Octopus to expose write to read only errors before they hit production.
@abMatGit @pboling What did you guys end up doing to address this in your apps?
Were you able to come up with a work-around? We are also experiencing this issue and it would help to know how you proceeded.
Thanks to both of you in advance!
My current workaround:
Add a rake task to enhance db:create
db:drop
tasks
namespace :octopus do
task on: :environment do
ActiveRecord::Base.clear_all_connections!
Octopus.enable!
end
task off: :environment do
ActiveRecord::Base.clear_all_connections!
Octopus.disable!
end
end
Rake::Task['db:create'].enhance(['octopus:off']) do Rake::Task['octopus:on'].invoke end
Rake::Task['db:drop'].enhance(['octopus:off']) do Rake::Task['octopus:on'].invoke end
2. Patch Octopus module:
module Octopus class << self def disable! @@enabled = false end
def enable!
@@enabled = true
end
def enabled_with_additional_check?
enabled_without_additional_check? && @@enabled
end
alias_method :enabled_without_additional_check?, :enabled?
alias_method :enabled?, :enabled_with_additional_check?
end end Octopus.enable!
@jughead thanks for the workaround.
Didn't you mean to invoke octopus:off
after db:drop
(instead of octopus:on
) ?
This works better for me, otherwise chaining rake db:drop db:create
fails, because db:drop
would keep Octopus enabled with no existing database.
The problem with this approach is that passing in tasks to the arguments of the enhance
method adds them as prerequisites. As such, they only get invoked once, so chaining db:create
and db:drop
may break.
I was able to get this to work more consistently with this:
Rake::Task['db:create'].actions.unshift Proc.new {
Rake::Task['octopus:patch'].invoke
Octopus.disable!
}
Rake::Task['db:create'].enhance do
Rake::Task['octopus:patch'].invoke
Octopus.enable!
end
Rake::Task['db:drop'].actions.unshift Proc.new {
Rake::Task['octopus:patch'].invoke
Octopus.disable!
}
Rake::Task['db:drop'].enhance do
Rake::Task['octopus:patch'].invoke
Octopus.enable!
end
Where there's a task octopus:patch
that does the monkey patching. As it's a rake task, it will only ever get called once.
Thank you @evanboho
Can you share your octopus:patch
rake task please?
Hello all, is there any update on this issue? thanks :)
There is simpler solution. You can put
Octopus.environments=[]
in Rakefile and it will do the trick.
Hey guys! There seems to be an interesting issue related to
db:create
rake tasks that were failing. This is a synopsis of our research (thanks @camertron):Issue:
When running
bundle exec rake db:create
rake task on a fresh rails server, using mysql2 adapters, we get the following error:What seems to be the issue here is that we are calling the create task: here. The
connection
is anOctopus::Proxy
class which when calling thecreate_database
method, hitsOctopus::Proxy#method_missing
which eventually delegates to: safe_connection's connectionThe problem here is two things: Rails
db:create
rake task establishes the connection with a database configuration{ 'database' => nil }
: here The Octopus is overriding this connection withconnection_pool.connection
which uses a database configuration{ 'database' => value in yaml file}
. This connection raises theUnknown database
issue.Proposed solution:
Alias the
establish_connection
method to explicitly and return anestablish_connection_without_octopus
connection.This will cause
establish_connection configuration_without_database
to return aMySQL2::Adapter
class instead of aOctopus::Proxy
class, from which we can successfully callconnection.create_database
and bypassOctopus::Proxy#method_missing
Replication stack of issue:
Gemfile:
Database.yml:
Shards.yml: