octopus
octopus copied to clipboard
saving a relation with using(:slave) causes additional where clauses to multiply
If I am in an environment where octopus is enabled, and I save an intermediate relation into a variable that uses using(:shard), then additional calls to that relation will permanently modify it. This won't happen in development mode, where I haven't added "development" to the "environments" array in shards.yml, and it won't happen if I skip the "using(:shard)", and it only happens if I save the relation into an intermediate variable.
This demo is a stripped down example; in reality, I'm saving a base relation and then running it on various created_at ranges, and only the first one gives me correct results.
Demo:
irb(main):022:0> base = User.using(:slave)
=> User(id: integer, login: string, created_at: datetime)
irb(main):035:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1"
irb(main):036:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1"
irb(main):037:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1"
irb(main):038:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1"
It looks like if the result responds to :all it will modify the scope klass. From what I can tell this was the functionality set way back in 2010 (after change 1435638376a7d203eb34a1cdbc9ebf8a3fe84058), but I'm not sure I understand the motivation for that change.
ScopeProxy.rb
def method_missing(method, *args, &block)
result = run_on_shard { @klass.send(method, *args, &block) }
if result.respond_to?(:all)
@klass = result
return self
end
result
end
If you remove the "if" clause from the code the above scenario works. I haven't tried the tests to see what that breaks though ;)
Bump - I am observing this in our code as well.
@platphorm did you try making that change in production? Are there any side effects you're aware of?
@dvandersluis no, we can not afford to publish experimental code to production. we just worked around this issue.
@knodi makes sense!