Skip to content

Commit e021458

Browse files
committed
firestore timeout
1 parent 4f76910 commit e021458

5 files changed

Lines changed: 96 additions & 51 deletions

File tree

infra/bigquery-export/firestore.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,23 @@ import { BigQueryExport } from './bigquery.js'
33

44
export class FirestoreBatch {
55
constructor () {
6-
this.firestore = new Firestore()
6+
this.firestore = new Firestore({
7+
// Increase timeout to 10 minutes for large batch operations
8+
gaxOptions: {
9+
grpc: {
10+
max_receive_message_length: 100 * 1024 * 1024, // 100MB
11+
max_send_message_length: 100 * 1024 * 1024, // 100MB
12+
'grpc.max_connection_idle_ms': 5 * 60 * 1000, // 5 minutes
13+
'grpc.keepalive_time_ms': 30 * 1000, // 30 seconds
14+
'grpc.keepalive_timeout_ms': 60 * 1000, // 1 minute
15+
'grpc.keepalive_permit_without_calls': true
16+
}
17+
}
18+
})
719
this.bigquery = new BigQueryExport()
8-
this.batchSize = 500
9-
this.maxConcurrentBatches = 200
20+
this.batchSizeDelete = 500
21+
this.batchSizeWrite = 400 // Reduced batch size for better performance
22+
this.maxConcurrentBatches = 100 // Reduced concurrent batches to avoid overwhelming
1023
}
1124

1225
queueBatch (operation) {
@@ -28,14 +41,34 @@ export class FirestoreBatch {
2841

2942
async commitBatches () {
3043
console.log(`Committing ${this.batchPromises.length} batches to ${this.collectionName}`)
44+
3145
await Promise.all(
32-
this.batchPromises.map(async (batchPromise) => await batchPromise.commit()
33-
.catch((error) => {
34-
console.error('Error committing batch:', error)
35-
throw error
36-
})
37-
)
46+
this.batchPromises.map(async (batchPromise, index) => {
47+
const retryCount = 3
48+
let lastError
49+
50+
for (let attempt = 1; attempt <= retryCount; attempt++) {
51+
try {
52+
await batchPromise.commit()
53+
return
54+
} catch (error) {
55+
lastError = error
56+
console.warn(`Batch ${index} attempt ${attempt} failed:`, error.message)
57+
58+
if (attempt < retryCount) {
59+
// Exponential backoff: 2^attempt seconds
60+
const delayMs = Math.pow(2, attempt) * 1000
61+
console.log(`Retrying batch ${index} in ${delayMs}ms...`)
62+
await new Promise(resolve => setTimeout(resolve, delayMs))
63+
}
64+
}
65+
}
66+
67+
console.error(`Batch ${index} failed after ${retryCount} attempts:`, lastError)
68+
throw lastError
69+
})
3870
)
71+
3972
this.batchPromises = []
4073
}
4174

@@ -71,7 +104,7 @@ export class FirestoreBatch {
71104
}
72105

73106
while (true) {
74-
const snapshot = await collectionQuery.limit(this.batchSize * this.maxConcurrentBatches).get()
107+
const snapshot = await collectionQuery.limit(this.batchSizeDelete * this.maxConcurrentBatches).get()
75108
if (snapshot.empty) {
76109
break
77110
}
@@ -127,7 +160,8 @@ export class FirestoreBatch {
127160

128161
async export (query, exportConfig) {
129162
this.firestore.settings({
130-
databaseId: exportConfig.database
163+
databaseId: exportConfig.database,
164+
timeout: 10 * 60 * 1000 // 10 minutes timeout
131165
})
132166
this.collectionName = exportConfig.collection
133167
this.collectionType = exportConfig.type

infra/tf/.terraform.lock.hcl

Lines changed: 26 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/tf/functions/main.tf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ terraform {
99
}
1010
}
1111

12-
resource "google_project_iam_member" "project" {
12+
resource "google_project_iam_member" "function_identity" {
1313
for_each = toset(["roles/bigquery.jobUser", "roles/dataform.serviceAgent", "roles/run.invoker", "roles/run.jobsExecutorWithOverrides", "roles/datastore.user", "roles/storage.objectUser"])
1414

1515
project = var.project
@@ -31,8 +31,10 @@ resource "google_bigquery_connection" "remote-functions" {
3131
cloud_resource {}
3232
}
3333

34-
resource "google_project_iam_member" "bigquery-remote-functions-connector" {
34+
resource "google_project_iam_member" "bigquery-connection-remote-functions" {
35+
for_each = toset(["roles/run.invoker"])
36+
3537
project = var.project
36-
role = "roles/run.invoker"
38+
role = each.value
3739
member = "serviceAccount:${google_bigquery_connection.remote-functions.cloud_resource[0].service_account_id}"
3840
}

infra/tf/functions/output.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "google_bigquery_connection-remote_functions-id" {
2+
description = "The connection ID for the remote functions BigQuery connection."
3+
value = google_bigquery_connection.remote-functions.id
4+
}
5+
6+
output "remote_functions_connection_service_account_id" {
7+
description = "The service account ID associated with the remote functions BigQuery connection."
8+
value = google_bigquery_connection.remote-functions.cloud_resource[0].service_account_id
9+
}

infra/tf/main.tf

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,6 @@ locals {
2828
function_identity = "cloud-function@httparchive.iam.gserviceaccount.com"
2929
}
3030

31-
module "dataform_export" {
32-
source = "./dataform_export"
33-
34-
project_number = local.project_number
35-
region = local.region
36-
function_identity = local.function_identity
37-
function_name = "dataform-export"
38-
remote_functions_connection = google_bigquery_connection.remote-functions.id
39-
}
40-
4131
module "dataform_trigger" {
4232
source = "./dataform_trigger"
4333

@@ -74,3 +64,14 @@ module "functions" {
7464
function_identity = local.function_identity
7565
edit_datasets = local.edit_datasets
7666
}
67+
68+
module "dataform_export" {
69+
source = "./dataform_export"
70+
71+
project_number = local.project_number
72+
region = local.region
73+
function_identity = local.function_identity
74+
function_name = "dataform-export"
75+
remote_functions_connection = module.functions.google_bigquery_connection-remote_functions-id
76+
depends_on = [module.functions]
77+
}

0 commit comments

Comments
 (0)