You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Brief Description of Feature:
We should add a Readyset.exclude method that allows users to annotate blocks of code that exist within a Readyset.route block from being routed to ReadySet.
Background:
It is convenient to be able to route all the queries in given controller actions or blocks of code to ReadySet; however, there may be one or two queries that should not be routed to ReadySet (e.g. queries that are unsupported by ReadySet). In such cases, a Readyset.exclude method would provide a way to ensure that the queries are routed to the database instead.
From the user's perspective:
In a given Readyset.route block, a user would annotate the unsupported query with Readyset.exclude:
Readyset.routedousers=User.where(active: true)# ReadySet does not support HAVINGorders=Readyset.excludedoOrder.select("created_at, sum(total) as total_price").group("created_at").having("sum(total) > ?",200)endend
Optional information to add
Proposed Solution:
This gets a bit tricky. Internally, Readyset.route will be using ActiveRecord::Base.connected_to to route queries to ReadySet. In our definition of Readyset.route, we'll need to store the prior role, shard, and preventing_writes associated with the connection that was being used before we connected to ReadySet. I believe we can do this by invoking:
ActiveRecord::Base.current_role
ActiveRecord::Base.current_shard
ActiveRecord::Base.current_preventing_writes
We will need to store this information thread-locally. Luckily, ActiveSupport::CurrentAttributes provides such an interface for us to exploit. We can subclass this class and expose an attribute for the above information. When the exclude block exits, we'll reset the information to nil. We may want to use an ensure to be sure that the state is reset upon an error.
It would be a runtime error to call Readyset.exclude outside of the context of a connection to ReadySet.
The text was updated successfully, but these errors were encountered:
I think I'm going to hold off on doing this for now. It's not as simple as invoking ActiveRecord::Base.current_role, etc. because different subclasses of ActiveRecord::Base can be connected to different shards/roles. We'd need to store connection state for every abstract subclass of ActiveRecord::Base whenever we invoke Readyset.route in order to reproduce the state of the world when call Readyset.exclude in order to ensure that we correctly "undo" the outer call to Readyset.route.
This is technically possible, but I think it has the potential to get pretty hairy and error-prone. Given that users have many workarounds (using Readyset.route more granularly, manually wrapping queries in connected_to blocks, etc.), I think we should deprioritize this until we get an explicit ask for it.
Brief Description of Feature:
We should add a
Readyset.exclude
method that allows users to annotate blocks of code that exist within aReadyset.route
block from being routed to ReadySet.Background:
It is convenient to be able to route all the queries in given controller actions or blocks of code to ReadySet; however, there may be one or two queries that should not be routed to ReadySet (e.g. queries that are unsupported by ReadySet). In such cases, a
Readyset.exclude
method would provide a way to ensure that the queries are routed to the database instead.From the user's perspective:
In a given
Readyset.route
block, a user would annotate the unsupported query withReadyset.exclude
:Optional information to add
Proposed Solution:
This gets a bit tricky. Internally,
Readyset.route
will be usingActiveRecord::Base.connected_to
to route queries to ReadySet. In our definition ofReadyset.route
, we'll need to store the prior role, shard, and preventing_writes associated with the connection that was being used before we connected to ReadySet. I believe we can do this by invoking:ActiveRecord::Base.current_role
ActiveRecord::Base.current_shard
ActiveRecord::Base.current_preventing_writes
We will need to store this information thread-locally. Luckily,
ActiveSupport::CurrentAttributes
provides such an interface for us to exploit. We can subclass this class and expose an attribute for the above information. When the exclude block exits, we'll reset the information tonil
. We may want to use anensure
to be sure that the state is reset upon an error.It would be a runtime error to call
Readyset.exclude
outside of the context of a connection to ReadySet.The text was updated successfully, but these errors were encountered: