Skip to content

fix: reuse Azure and Oracle clients across requests; document DI lifetime audit - #71

Merged
mmalkhatib merged 1 commit into
mainfrom
muhannad/fix-as-oc-client-lifetime
Aug 25, 2026
Merged

fix: reuse Azure and Oracle clients across requests; document DI lifetime audit#71
mmalkhatib merged 1 commit into
mainfrom
muhannad/fix-as-oc-client-lifetime

Conversation

@mmalkhatib

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #70 (S3 client-lifetime fix, live prod incident). Audited the other three network-backed providers for the same class of bug — building a fresh SDK client on every DI resolution instead of reusing a pooled, thread-safe one.

  • Azure (SW.CloudFiles.AS): same AddTransient bug as S3, and worse. The DI extension registered a singleton BlobContainerClient that was never actually used — CloudFilesService's constructor built its own client via a field initializer instead of taking one as a parameter. In the non-managed-identity auth path, that means a synchronous, blocking GetBlobContainers() list call on every single construction, not just a fresh handshake. Fixed: CloudFilesService now takes BlobContainerClient via constructor injection (reusing the registered singleton), ICloudFilesService is now AddSingleton.
  • Oracle (SW.CloudFiles.OC): was AddScoped — milder than Transient, but still built a fresh ObjectStorageClient + UploadManager (plus a disk read of the PEM/config file) once per HTTP request. Changed to AddSingleton.
  • Google Cloud (SW.CloudFiles.GC): already correct — ICloudFilesService is AddScoped, but the real StorageClient/UrlSigner are AddSingleton and injected, so no repeated client construction regardless. No change.

Also documents the full audit in CLAUDE.md and adds client-reuse/timeout notes to README.md.

None of Azure/GCS/Oracle are used by any Traxis service today (only S3 is) — this is library-quality debt, not a live incident.

Test plan

  • dotnet build clean across the whole solution
  • SW.CloudFiles.AS.UnitTest / SW.CloudFiles.OC.UnitTest fail identically with and without this change (confirmed by reverting and re-running) — pre-existing, need live cloud credentials, consistent with CI's run-tests: 'false'

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: simplify9/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65707533-8981-4d21-9907-7f9b4eae4c9b


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…time audit

Prompted by the S3 client-lifetime incident fixed in 8.1.11, audited the
other network-backed providers for the same class of bug (building a
fresh SDK client on every DI resolution instead of reusing a pooled,
thread-safe one):

- Azure (SW.CloudFiles.AS): same AddTransient bug as S3 had, and worse —
  the DI extension registered a singleton BlobContainerClient that was
  never actually used, since CloudFilesService's constructor built its
  own client instead of taking one as a parameter. In the non-managed-
  identity auth path that means a synchronous, blocking GetBlobContainers
  list call on every single construction. Fixed: CloudFilesService now
  takes BlobContainerClient via constructor injection (reusing the
  registered singleton), and ICloudFilesService is now AddSingleton.

- Oracle (SW.CloudFiles.OC): was AddScoped, so a fresh ObjectStorageClient
  + UploadManager (and a disk read of the PEM/config file) were built
  once per HTTP request rather than once per resolution. Changed to
  AddSingleton so the client is built once for the process lifetime.

- Google Cloud (SW.CloudFiles.GC): already correct — ICloudFilesService
  is AddScoped, but the actual StorageClient/UrlSigner are AddSingleton
  and injected, so no repeated client construction. No change needed.

No known consumer currently uses Azure/GCS/Oracle (only S3 is actively
used today), so this is library-quality debt rather than a live incident,
unlike the S3 fix. Documented the full audit in CLAUDE.md and added the
client-reuse/timeout notes to README.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mmalkhatib
mmalkhatib force-pushed the muhannad/fix-as-oc-client-lifetime branch from 4521b9e to 75737e4 Compare August 25, 2026 13:58
@mmalkhatib
mmalkhatib merged commit 7ef1283 into main Aug 25, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants