-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subclass switching #136
Subclass switching #136
Conversation
4ff1179
to
f66c783
Compare
@@ -141,8 +141,6 @@ def model.on_slave_by_default? | |||
left_reflection.klass.on_slave_by_default? | |||
end | |||
|
|||
# also transfer the sharded-ness of the left table to the join model | |||
model.not_sharded unless model.left_reflection.klass.is_sharded? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure :|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems super sketchy that we call not_sharded ... maybe this is a 1-off join model ... which means that it should now be model.sharded if foo
instead ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a test for this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried adding a test - it's not exactly obvious where to put it though
f5f238f
to
c00a1b6
Compare
d011f2a
to
a1a1f97
Compare
I'm a little scared that an inheritance change would break all existing usages and also introduce bugs where things like |
end | ||
unless config['shard_names'].include?(options[:shard]) | ||
raise "Did not find shard #{options[:shard]} in configurations" | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these validations could go out as their own PR so we can test them quickly and make this PR smaller ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure we can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except that options[:shard]
can still be nil
which cannot be found in config['shard_names']. So the validations need to be tweaked a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's is one big and scary PR. Should we test it on one application before merging? |
I considered making it a module one would extend as well. I can give it a shot. This will be a new major version and will require changes to existing code so I'm not too worried about breaking existing usage. |
I imagine releasing it as ARS 4.0 beta and test it with the K8s HC branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for beta tag
a1a1f97
to
bfd516d
Compare
587958a
to
9d1182c
Compare
9746156
to
9d1182c
Compare
class ShardedModel < ActiveRecord::Base | ||
self.abstract_class = true | ||
|
||
extend ActiveRecordShards::Ext::ShardedModel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this better than def self.is_sharded?
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean why am I extending a module over just defining a method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that’s what I meant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need the module to extend into various ActiveRecord classes where I can't easily change the superclass (models from gems). As I need a module I might as well reuse the module here to keep it slightly more dry.
edf44fd
to
268e74d
Compare
current_shard_selection.shard = options[:shard] | ||
end | ||
|
||
if options.key?(:slave) | ||
current_shard_selection.on_slave = options[:slave] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do/should we support master/slave switching without switching shards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you're getting at?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me neither. This is fine.
ActiveSupport::Deprecation.warn("Calling not_sharded is deprecated. "\ | ||
"Please ensure to still read from the "\ | ||
"account db slave after removing the "\ | ||
"call.") | ||
end | ||
|
||
def is_sharded? # rubocop:disable Naming/PredicateName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we seize the moment and rename .is_sharded?
to .sharded?
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments but 👍 and ❤️ to the overall plan.
prefer changes are nicer ... rename in old branch and bump in classic then
fix everything up
…On Wed, Oct 25, 2017 at 12:24 PM, Benjamin Quorning < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In lib/active_record_shards/model.rb
<#136 (comment)>
:
> @@ -3,24 +3,14 @@
module ActiveRecordShards
module Model
def not_sharded
- if self != ActiveRecord::Base && self != base_class
- raise "You should only call not_sharded on direct descendants of ActiveRecord::Base"
- end
- self.sharded = false
+ ActiveSupport::Deprecation.warn("Calling not_sharded is deprecated. "\
+ "Please ensure to still read from the "\
+ "account db slave after removing the "\
+ "call.")
end
def is_sharded? # rubocop:disable Naming/PredicateName
Should we seize the moment and rename .is_sharded? to .sharded??
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#136 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAsZ8X8yvcMmg_hJGKiYrolDc80oys4ks5svwxkgaJpZM4P1cOw>
.
|
I'm not sure what you're saying? |
I think it’s a threading fail. The
|
Ah! |
It does not make sense to have a default shard so we're removing this
We don't want to have a "selection" where nothing is selected as that may cause weird issues. For instance it may result in not being able to get the schema of sharded tables.
If we're using ARS we expect shards to be configured. We don't want to silently fail in case the configuration is missing.
If we're missing configuration we raise an exception at the point we discover the missing configuration. This is to avoid accidentally calling .shard= with nil.
We move the state manipulating on_slave= call to after we check that we're actually able to perform the shard switch. Otherwise we may accidentally update state and then see an exception leaving us in an inconsistent state.
When selecting a new shard the user should always select an actual shard. It does not make sense to select NO_SHARD.
When we ask for the shard we must ensure that we do have a shard selected.
It no longer makes sense to talk about being able to switch to shard and back as unsharded models will now always be unsharded and sharded models will now always be sharded.
I don't even know why we're testing behaviour of ARS in an unsharded environment.
From now on sharded models must inherit from ActiveRecordShards::ShardedModel - and no longer will users need to use the "not_sharded" instruction to mark models not sharded. By doing this we've simplified the logic around sharding as ActiveRecord::Base no longer needs to be part of the calculation around wether a class is sharded or not. It's now purely defined in terms of inheritance, inheriting from ShardedModel means the model is sharded.
This is no longer used
We are method chaining not_sharded in ZendeskDatabaseSupport and adding default reading from the slave for unsharded models. To help the transition we'll keep the not_sharded method around until we can remove it from the dependents.
Instead of checking class inheritance we can just call a class method. This way we can define it to be false for ActiveRecord::Base and override it in sharded subclasses. This also gives us the possibility of using a module (or just plain defining the method in any random class).
Global state in tests, yay
4b0a309
to
db1760d
Compare
I've merged #146 bumping to beta-4.0.0.beta1 on the v4 branch. Does anyone know how to release this onto rubygems.org? |
v4.0.0.beta1 has been released 🎉 ✨ |
Another stab at making ARS a little more understandable. The gist of it is that we try to isolate the ActiveRecordShards logic in a class instead of monkey patching
ActiveRecord::Base
.This PR changes a bunch of things around ActiveRecordShards. First up it drops support for Rails < 5. It also removes the migration parts of ARS as those can be better handled separately. It introduces a new
ActiveRecordShards::ShardedModel
class which sharded models must now inherit from instead ofActiveRecord::Base
. On the flip side thenot_sharded
instruction is no longer necessary or supported. These changes should make ActiveRecord classes not inheriting fromActiveRecordShards::ShardedModel
behave more like they would when not using ActiveRecordShards.This also removes support for the
default_shard
idea as it doesn't make a lot of sense to talk about a default shard. If you want a random shard just use the first shard available.Additionally this introduces the requirement that a shard must always be selected. It's no longer possible to say
on_shard(nil)
. Only numeric shards are accepted.Future work on this would be to separate sharding from master/slave logic and move the patches to
ActiveRecord::Base
down to theActiveRecordShards::ShardedModel
class makingActiveRecord::Base
totally ignorant of ActiveRecordShards.With these changes we'll need to release a new major version of ARS to comply with SemVer.