mirror of
https://github.com/immich-app/geoshenanigans.git
synced 2026-09-30 13:23:08 +08:00
feat: d1 global read replicas (#149)
This commit is contained in:
@@ -31,14 +31,6 @@ resource "cloudflare_workers_script" "tiles" {
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "d1_database_binding" {
|
||||
for_each = data.terraform_remote_state.tiles_state.outputs.d1_regional_databases
|
||||
content {
|
||||
name = "D1_${d1_database_binding.key}"
|
||||
database_id = d1_database_binding.value
|
||||
}
|
||||
}
|
||||
|
||||
d1_database_binding {
|
||||
database_id = data.terraform_remote_state.tiles_state.outputs.d1_global_database
|
||||
name = "D1_GLOBAL"
|
||||
@@ -62,15 +54,3 @@ resource "cloudflare_workers_domain" "tiles_prod" {
|
||||
service = cloudflare_workers_script.tiles.id
|
||||
zone_id = data.cloudflare_zone.immich_cloud.zone_id
|
||||
}
|
||||
|
||||
import {
|
||||
for_each = var.env == "prod" ? { import : cloudflare_workers_script.tiles } : {}
|
||||
to = cloudflare_workers_script.tiles
|
||||
id = "${var.cloudflare_account_id}/tiles-prod"
|
||||
}
|
||||
|
||||
import {
|
||||
for_each = var.env == "prod" ? { import : cloudflare_workers_domain.tiles } : {}
|
||||
to = cloudflare_workers_domain.tiles
|
||||
id = "${var.cloudflare_account_id}/17b3213004b9d5f077563e3c4ea3171ef9d0c5fc"
|
||||
}
|
||||
|
||||
+2
-12
@@ -89,6 +89,8 @@ async function handleRequest(
|
||||
deferredRepository: CloudflareDeferredRepository,
|
||||
metrics: IMetricsRepository,
|
||||
) {
|
||||
const d1Repository = new CloudflareD1Repository(env.D1_GLOBAL, metrics);
|
||||
void d1Repository.query('SELECT 1');
|
||||
const cacheResponse = async (response: Response): Promise<Response> => {
|
||||
if (!response.body) {
|
||||
throw new Error('Response body is undefined');
|
||||
@@ -177,24 +179,12 @@ async function handleRequest(
|
||||
weur: env.BUCKET_WEUR,
|
||||
oc: env.BUCKET_OC,
|
||||
};
|
||||
const d1Map: Record<R2BucketRegion, D1Database> = {
|
||||
apac: env.D1_APAC,
|
||||
eeur: env.D1_EEUR,
|
||||
enam: env.D1_ENAM,
|
||||
wnam: env.D1_WNAM,
|
||||
weur: env.D1_WEUR,
|
||||
oc: env.D1_OC,
|
||||
};
|
||||
const colo = request.cf?.colo || '';
|
||||
const buckets: R2BucketRegion[] = preferredBuckets[colo] || ['weur', 'eeur', 'enam', 'wnam', 'apac', 'oc'];
|
||||
console.log('Buckets', buckets);
|
||||
const filteredBucketMap = Object.fromEntries(
|
||||
Object.entries(bucketMap).filter(([key]) => buckets.includes(key as R2BucketRegion)),
|
||||
);
|
||||
const filteredD1Map = Object.fromEntries(
|
||||
Object.entries(d1Map).filter(([key]) => buckets.includes(key as R2BucketRegion)),
|
||||
);
|
||||
const d1Repository = new CloudflareD1Repository(filteredD1Map, metrics);
|
||||
|
||||
const storageRepository = new R2StorageRepository(filteredBucketMap, env.DEPLOYMENT_KEY, metrics);
|
||||
const pmTilesService = await metrics.monitorAsyncFunction({ name: 'pmtiles_init' }, PMTilesService.init)(
|
||||
|
||||
+9
-12
@@ -15,26 +15,23 @@ import { monitorAsyncFunction } from './monitor';
|
||||
|
||||
export class CloudflareD1Repository implements IDatabaseRepository {
|
||||
constructor(
|
||||
private databases: { [key: string]: D1Database },
|
||||
private database: D1Database,
|
||||
private metrics: IMetricsRepository,
|
||||
) {}
|
||||
|
||||
async query(query: string, ...values: unknown[]) {
|
||||
const metric = Metric.create('d1_query');
|
||||
const { key: databaseKey, resp } = await Promise.race(
|
||||
Object.entries(this.databases).map(async ([key, database]) => {
|
||||
const resp = await database
|
||||
.prepare(query)
|
||||
.bind(...values)
|
||||
.run();
|
||||
return { key, resp };
|
||||
}),
|
||||
);
|
||||
const resp = await this.database
|
||||
.withSession('first-unconstrained')
|
||||
.prepare(query)
|
||||
.bind(...values)
|
||||
.run();
|
||||
|
||||
console.log('resp_meta', resp.meta);
|
||||
metric
|
||||
.durationField('duration')
|
||||
.addTag('database_key', databaseKey)
|
||||
.addTag('served_by_region', resp.meta.served_by as string)
|
||||
.addTag('query', query)
|
||||
.addTag('served_by_region', resp.meta.served_by_region as string)
|
||||
.addTag('served_by_primary', (resp.meta.served_by_primary as boolean).toString())
|
||||
.intField('rows_read', resp.meta.rows_read)
|
||||
.intField('sql_duration', resp.meta.duration)
|
||||
|
||||
Vendored
+5737
-17
File diff suppressed because it is too large
Load Diff
+3
-28
@@ -12,34 +12,9 @@ id = "5a4b82694e8b490db8b8904cdaea4f00"
|
||||
preview_id = "5a4b82694e8b490db8b8904cdaea4f00"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_WNAM"
|
||||
database_name = "tiles-wnam"
|
||||
database_id = "837aa5e4-f404-4613-b30c-34f3b8bca150"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_ENAM"
|
||||
database_name = "tiles-enam"
|
||||
database_id = "f63d8430-3e5b-42bd-a6a6-45fd3f552a9a"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_WEUR"
|
||||
database_name = "tiles-weur"
|
||||
database_id = "ce5b6777-c533-4ff1-91a4-d6b5e94293da"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_EEUR"
|
||||
database_name = "tiles-eeur"
|
||||
database_id = "538b5ef8-9a73-4bd8-a088-3a43c992cfd0"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_APAC"
|
||||
database_name = "tiles-apac"
|
||||
database_id = "d8501ddc-adea-48b4-a577-074640b56493"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "D1_OC"
|
||||
database_name = "tiles-oc"
|
||||
database_id = "403f37a6-ebe8-4d05-9ffb-088aa73fa014"
|
||||
binding = "D1_GLOBAL"
|
||||
database_name = "tiles"
|
||||
database_id = "c60521e7-59bd-4186-81e7-9a676edf9b75"
|
||||
|
||||
# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files.
|
||||
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets
|
||||
|
||||
Reference in New Issue
Block a user