Skip to content
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

Feature: Automatic Connection Switching & Horizontal Sharding #475

Open
crimson-knight opened this issue May 3, 2023 · 0 comments
Open
Assignees

Comments

@crimson-knight
Copy link
Member

This is pretty important, especially since most large Rails apps have moved to use the automatic connection switching between readers/writers, and probably also for sharding.

It is currently possible to have multiple connections like this:

Granite::Connections << Granite::Adapter::Mysql.new(name: "mysql_primary", url: "YOUR_PRIMARY_DATABASE_URL")
Granite::Connections << Granite::Adapter::Mysql.new(name: "mysql_reader", url: "YOUR_READER_DATABASE_URL")

However, this does not set the actual roles for the db's shown, and you can only select a single database connection from the model.

I think we'll need to modify the connection macro to allow accepting a NamedTuple or Tuple so we can pass in some configuration settings like:

{
  writer: "mysql_primary",
  reader: "mysql_reader"
}

The current connection macro is here:

macro connection(name)

macro connection(connection_details)
  {% if connection_details.is_a?(StringLiteral) %}
  class_getter adapter : Granite::Adapter::Base = Granite::Connections[{{connection_details}}]
  {% elsif connection_details.is_a?(TupleLiteral) || connection_details.is_a?(NamedTupleLiteral) %}
  # Put the code here to set the reader/writer
  {% else %}
  # Probably don't actually want to raise here like this
  raise "No registered connection with the name '{{name.id}}'"
  {% end %}
end

Just throwing this out there for now, but I think it'll be easier than it may first appear to add automatic connection switching.

We would also need:

  • A variable to track when the last write transaction was done to get the time since the last write
  • A configuration to set the delay from switching between the writer and the reader, probably 2 seconds to allow for propagation
  • A way to tell if the action being performed is a read or write action. This is pretty straightforward since writing actions are insert, update & upsert and most other queries will be to read. We want to default to using the reader as often as possible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant