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: Read replica support #476

Merged
merged 27 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2ce89df
added variables for tracking time since last write
a-alhusaini May 5, 2023
dcaa7d2
added variables to store reader and writer db connections
a-alhusaini May 7, 2023
b4010f4
switched from time.utc to time.monotonic for tracking time since last…
a-alhusaini May 7, 2023
fcec217
Added methods to switch between connections.
a-alhusaini May 7, 2023
d6658ea
added instance variant of switch_to_writer_adapter for use with callb…
a-alhusaini May 7, 2023
b22e62b
Fixed typo in def switch_to_writer_adapter
a-alhusaini May 7, 2023
9bc3743
added logic to automatically switch to reader adapter
a-alhusaini May 7, 2023
438f04c
functions in querying now dynamically change adapter based on need
a-alhusaini May 7, 2023
d2fc1d0
ensure all methods in query builder that need primary database switch…
a-alhusaini May 7, 2023
c2eb32d
added better error message for invalid connections
a-alhusaini May 10, 2023
2bd49f1
groundwork for replica testing
a-alhusaini May 10, 2023
21878b2
fixed error where mysql tests don't run
a-alhusaini May 10, 2023
866e00a
Granite::Base.adapter class method now actually fetches current adapt…
a-alhusaini May 10, 2023
720005d
fixed typo. Invalid adapter_type for pg_with_replica
a-alhusaini May 10, 2023
f6cf749
fixed True to true. Added table name to ReplicatedChat.
a-alhusaini May 10, 2023
4e97c87
update specs
kalinon May 11, 2023
4f1ef67
Merge pull request #1 from kalinon/track_last_query
a-alhusaini May 11, 2023
431ed8e
spec updates
kalinon May 11, 2023
e531675
Merge pull request #2 from kalinon/track_last_query
a-alhusaini May 11, 2023
4976d11
Update .gitignore
crimson-knight May 15, 2023
6ab17b0
moved connection management logic to seperate module. Fixed bug where…
a-alhusaini May 20, 2023
74ff74c
fixed error where reader connection switch ignored specified wait per…
a-alhusaini May 21, 2023
8ecc010
moved default value for connection switch wait period to granite::co…
a-alhusaini May 21, 2023
76133f3
moved connection macro to connection management module
a-alhusaini May 21, 2023
e11cf7c
cleaned up code for fetching first connection
a-alhusaini May 21, 2023
058b414
finalized syntax for adding new connections to granite::connections
a-alhusaini May 21, 2023
122be6c
optimization: when reader & writer database are the same do not dupli…
a-alhusaini May 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PG_DATABASE_URL=postgres://granite:password@localhost:5432/granite_db
PG_REPLICA_URL=postgres://granite:password@localhost:5432/granite_db
robacarp marked this conversation as resolved.
Show resolved Hide resolved
MYSQL_DATABASE_URL=mysql://granite:password@localhost:3306/granite_db
MYSQL_REPLICA_URL=mysql://granite:password@localhost:3306/granite_replica_db
MYSQL_REPLICA_URL=mysql://granite:password@localhost:3306/granite_db
SQLITE_DATABASE_URL=sqlite3:./granite.db
SQLITE_REPLICA_URL=sqlite3:./granite_replica.db
CURRENT_ADAPTER=pg
Expand Down
14 changes: 6 additions & 8 deletions .github/workflows/spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ jobs:
with:
crystal: ${{ matrix.crystal }}
- name: Install shards
run: shards update --ignore-crystal-version
run: shards update --ignore-crystal-version --skip-postinstall --skip-executables
- name: Run tests
timeout-minutes: 2
run: crystal spec
env:
CURRENT_ADAPTER: sqlite
SQLITE_DATABASE_URL: sqlite3:./granite.db
MYSQL_DATABASE_URL: mysql://granite:password@localhost:3306/granite_db
PG_DATABASE_URL: postgres://granite:password@localhost:5432/granite_db
SQLITE_REPLICA_URL: sqlite3:./granite_replica.db
mysql-spec:
runs-on: ubuntu-latest
strategy:
Expand Down Expand Up @@ -71,15 +70,15 @@ jobs:
with:
crystal: ${{ matrix.crystal }}
- name: Install shards
run: shards update --ignore-crystal-version
run: shards update --ignore-crystal-version --skip-postinstall --skip-executables
- name: Run tests
timeout-minutes: 2
run: crystal spec
env:
CURRENT_ADAPTER: mysql
SQLITE_DATABASE_URL: sqlite3:./granite.db
MYSQL_DATABASE_URL: mysql://granite:password@localhost:3306/granite_db
PG_DATABASE_URL: postgres://granite:password@localhost:5432/granite_db
MYSQL_REPLICA_URL: mysql://granite:password@localhost:3306/granite_db
psql-spec:
runs-on: ubuntu-latest
strategy:
Expand Down Expand Up @@ -110,12 +109,11 @@ jobs:
with:
crystal: ${{ matrix.crystal }}
- name: Install shards
run: shards update --ignore-crystal-version
run: shards update --ignore-crystal-version --skip-postinstall --skip-executables
- name: Run tests
timeout-minutes: 2
run: crystal spec
env:
CURRENT_ADAPTER: pg
SQLITE_DATABASE_URL: sqlite3:./granite.db
MYSQL_DATABASE_URL: mysql://granite:password@localhost:3306/granite_db
PG_DATABASE_URL: postgres://granite:password@localhost:5432/granite_db
PG_REPLICA_URL: postgres://granite:password@localhost:5432/granite_db
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ shard.lock

# Ignore bin because they will be build with shards install
bin
.env_kalinon
a-alhusaini marked this conversation as resolved.
Show resolved Hide resolved
crimson-knight marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion spec/run_test_dbs.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ docker run --name mysql -d \
-e MYSQL_USER=granite \
-e MYSQL_PASSWORD=password \
-p 3306:3306 \
mysql:%{MYSQL_VERSION}
mysql:${MYSQL_VERSION}

docker run --name psql -d \
-e POSTGRES_USER=granite \
Expand Down
24 changes: 15 additions & 9 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ require "mysql"
require "pg"
require "sqlite3"

Granite::Connections << Granite::Adapter::Mysql.new(name: "mysql", url: ENV["MYSQL_DATABASE_URL"])
Granite::Connections << Granite::Adapter::Pg.new(name: "pg", url: ENV["PG_DATABASE_URL"])
Granite::Connections << Granite::Adapter::Sqlite.new(name: "sqlite", url: ENV["SQLITE_DATABASE_URL"])

# Connections with replicas
# TODO: Experiment to find a better API.
Granite::Connections.<<(name: "sqlite_with_replica", writer: ENV["SQLITE_DATABASE_URL"], reader: ENV["SQLITE_REPLICA_URL"], adapter_type: Granite::Adapter::Sqlite)
Granite::Connections.<<(name: "mysql_with_replica", writer: ENV["MYSQL_DATABASE_URL"], reader: ENV["MYSQL_REPLICA_URL"], adapter_type: Granite::Adapter::Mysql)
Granite::Connections.<<(name: "pg_with_replica", writer: ENV["PG_DATABASE_URL"], reader: ENV["PG_REPLICA_URL"], adapter_type: Granite::Adapter::Pg)
case ENV["CURRENT_ADAPTER"]?
when "pg"
Granite::Connections << Granite::Adapter::Pg.new(name: "pg", url: ENV["PG_DATABASE_URL"])
Granite::Connections.<<(name: "pg_with_replica", writer: ENV["PG_DATABASE_URL"], reader: ENV["PG_REPLICA_URL"], adapter_type: Granite::Adapter::Pg)
when "mysql"
Granite::Connections << Granite::Adapter::Mysql.new(name: "mysql", url: ENV["MYSQL_DATABASE_URL"])
Granite::Connections.<<(name: "mysql_with_replica", writer: ENV["MYSQL_DATABASE_URL"], reader: ENV["MYSQL_REPLICA_URL"], adapter_type: Granite::Adapter::Mysql)
when "sqlite"
Granite::Connections << Granite::Adapter::Sqlite.new(name: "sqlite", url: ENV["SQLITE_DATABASE_URL"])
Granite::Connections.<<(name: "sqlite_with_replica", writer: ENV["SQLITE_DATABASE_URL"], reader: ENV["SQLITE_REPLICA_URL"], adapter_type: Granite::Adapter::Sqlite)
when Nil
raise "Please set CURRENT_ADAPTER"
else
raise "Unknown adapter #{ENV["CURRENT_ADAPTER"]}"
end

require "spec"
require "../src/granite"
Expand Down