(meta server.WorkerControlMetadata)
| 316 | !reflect.DeepEqual(current.DuckLake, payload.DuckLake) { |
| 317 | needsRefresh = s3CredentialsChanged(current.DuckLake, payload.DuckLake) |
| 318 | if !needsRefresh { |
| 319 | // For aws_sdk/credential_chain, the underlying IAM credentials |
| 320 | // may have expired even though the payload fields haven't changed. |
| 321 | provider := server.S3ProviderForConfig(payload.DuckLake) |
| 322 | needsRefresh = provider == "aws_sdk" || provider == "credential_chain" |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | // Pick the connection used to swap the secret. controlDB is a side |
| 327 | // connection sharing the same DuckDB instance via *duckdb.Connector, with |
| 328 | // its own independent pool — so the CREATE OR REPLACE SECRET below never |
| 329 | // queues behind a long-running client query on the main DB. Fall back to |
| 330 | // the activation DB only when controlDB hasn't been wired (older/test |
| 331 | // paths that bypass createDBPair). |
| 332 | refreshDB := p.controlDB |
| 333 | if refreshDB == nil { |
| 334 | refreshDB = p.activation.db |
| 335 | } |
| 336 | refreshFn := p.refreshS3Secret |
| 337 | sem := p.duckLakeSem |
| 338 | p.mu.Unlock() |
| 339 | |
| 340 | // Phase 2 (unlocked): perform the slow I/O. Holding p.mu across this is a |
| 341 | // bug — RefreshS3Secret runs a CREATE OR REPLACE SECRET which can block |
no outgoing calls