Skip to content

feat(google): add Google Cloud Firestore providers - #8462

Merged
ReubenBond merged 25 commits into
dotnet:mainfrom
galvesribeiro:google-providers
Aug 10, 2026
Merged

ReubenBond merged 25 commits into
dotnet:mainfrom
galvesribeiro:google-providers

Conversation

@galvesribeiro

@galvesribeiro galvesribeiro commented Jun 3, 2023 •

Copy link
Copy Markdown
Member

This PR adds Google Cloud (GCP) providers to Orleans:

  • Firestore Providers (Clustering, Reminders and Persistence)
  • Firestore Grain Directory

The documents in Firestore for the Cluster/Storage/Reminder providers follow the structure bellow:

Orleans (Root collection)
-- Clustering (doc)
--> ClusterId (sub-collection)
----> ClusterVersionEntity (doc)
----> SiloInstanceEntity (doc)
-- Persistence (doc)
--> ServiceId (sub-collection)
----> GrainStateEntity (doc)
-- Reminders (doc)
--> ServiceId (sub-collection)
----> ReminderEntity (doc)
-- GrainDirectory (doc)
--> ClusterId (sub-collection)
----> GrainDirectoryEntity (doc)

Microsoft Reviewers: Open in CodeFlow

@galvesribeiro
galvesribeiro force-pushed the google-providers branch 9 times, most recently from f8617a7 to 3c1a182 Compare June 9, 2023 15:04
@galvesribeiro
galvesribeiro force-pushed the google-providers branch 7 times, most recently from 94bb87c to dc23a2d Compare June 14, 2023 17:08
@galvesribeiro galvesribeiro changed the title [WIP] Google Cloud (GCP) Providers Google Cloud (GCP) Providers Jun 16, 2023
@galvesribeiro
galvesribeiro force-pushed the google-providers branch 4 times, most recently from abf6661 to b18afca Compare June 20, 2023 02:41
Copilot AI review requested due to automatic review settings August 1, 2026 01:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new set of Orleans providers backed by Google Cloud Firestore (clustering, reminders, persistence, and grain directory), along with a dedicated test project and CI job to run against local Google emulators.

Changes:

  • Introduces new Firestore-backed provider projects under src/Google/ (shared Firestore data manager + provider implementations + hosting extensions).
  • Adds Orleans.Tests.Google test project with emulator helpers and functional/stress tests for the new providers.
  • Wires the new projects into the solution, package versions, InternalsVisibleTo, and GitHub Actions CI.
Show a summary per file
File Description
test/TestInfrastructure/TestExtensions/TestExtensions.csproj Grants internals access to new Orleans.Tests.Google test assembly.
test/Orleans.Runtime.Internal.Tests/RemindersTest/ReminderTableTestsBase.cs Adjusts reminder tests to align with new provider behavior and grain id creation.
test/Orleans.Runtime.Internal.Tests/Orleans.Runtime.Internal.Tests.csproj Grants internals access to new Orleans.Tests.Google test assembly.
test/Orleans.Runtime.Internal.Tests/MembershipTests/MembershipTableTestsBase.cs Makes shared membership test state accessible to derived provider tests.
test/Grains/TestInternalGrains/PersistenceTestGrains.cs Adds Google Firestore storage test grains.
test/Grains/TestGrainInterfaces/IPersistenceTestGrains.cs Adds interfaces for Google Firestore storage test grains.
test/Extensions/Google.Tests/Usings.cs Adds global xUnit using for Google tests project.
test/Extensions/Google.Tests/Reminders/FirestoreRemindersTests.cs Adds reminder table tests for Firestore reminders provider.
test/Extensions/Google.Tests/Persistence/FirestoreStorageProviderTests.cs Adds direct IGrainStorage tests for Firestore storage provider.
test/Extensions/Google.Tests/Persistence/FirestorePersistenceGrainTests.cs Adds cluster-level persistence grain tests using Firestore storage.
test/Extensions/Google.Tests/Persistence/Base_PersistenceGrainTests_GoogleStorage.cs Shared base test suite for Firestore persistence grain tests and perf/stress tests.
test/Extensions/Google.Tests/GrainDirectory/FirestoreGrainDirectoryTests.cs Adds grain directory tests for Firestore grain directory implementation.
test/Extensions/Google.Tests/Google.Tests.csproj New Google tests project wiring provider references and shared linked sources.
test/Extensions/Google.Tests/FirestoreDataManagerTests.cs Unit tests for shared FirestoreDataManager behavior (CRUD/query/batch).
test/Extensions/Google.Tests/FirestoreDataManagerStressTest.cs Stress-style tests for FirestoreDataManager high-volume upserts.
test/Extensions/Google.Tests/Emulators/storage.rules Firebase storage emulator rules used for local test emulators.
test/Extensions/Google.Tests/Emulators/GoogleEmulatorHost.cs Helper to detect emulator availability and set emulator env vars.
test/Extensions/Google.Tests/Emulators/firebase.json Emulator configuration used by firebase tools.
test/Extensions/Google.Tests/Emulators/EmulatorTest.cs Sanity checks that emulator is reachable and Firestore SDK can interact.
test/Extensions/Google.Tests/Emulators/Emulators.md Documentation for running Google emulators locally for tests.
test/Extensions/Google.Tests/Emulators/.firebaserc Firebase emulator project configuration.
test/Extensions/Google.Tests/Clustering/FirestoreSiloInstanceManagerTests.cs Tests for Firestore-based membership manager behavior.
test/Extensions/Google.Tests/Clustering/FirestoreMembershipTableTests.cs Membership/gateway tests for Firestore clustering provider.
src/Orleans.TestingHost/Orleans.TestingHost.csproj Grants internals access to new Orleans.Tests.Google test assembly.
src/Orleans.Core/Orleans.Core.csproj Grants internals access to new Orleans.Tests.Google test assembly.
src/Google/Shared/Utils/Utils.cs Shared helpers (timestamp formatting, id sanitization, grain id encoding).
src/Google/Shared/Storage/GoogleCloudOptions.cs Base options for Google Cloud provider configuration.
src/Google/Shared/Storage/FirestoreOptions.cs Firestore-specific options + validation.
src/Google/Shared/Storage/FirestoreEntity.cs Base Firestore entity abstraction (Id/ETag + update fields).
src/Google/Shared/Storage/FirestoreDataManager.cs Core Firestore CRUD/query/batch/transaction abstraction used by providers.
src/Google/Orleans.Reminders.GoogleFirestore/ReminderEntity.cs Firestore entity model for reminders.
src/Google/Orleans.Reminders.GoogleFirestore/Orleans.Reminders.GoogleFirestore.csproj New Firestore reminders provider project packaging and dependencies.
src/Google/Orleans.Reminders.GoogleFirestore/GoogleFirestoreReminderTable.cs Firestore implementation of IReminderTable.
src/Google/Orleans.Reminders.GoogleFirestore/GoogleFirestoreReminderServiceExtensions.cs Hosting/service collection extensions for Firestore reminders provider.
src/Google/Orleans.Persistence.GoogleFirestore/Orleans.Persistence.GoogleFirestore.csproj New Firestore persistence provider project packaging and dependencies.
src/Google/Orleans.Persistence.GoogleFirestore/GrainStateEntity.cs Firestore entity model for persisted grain state.
src/Google/Orleans.Persistence.GoogleFirestore/GoogleFirestoreStorage.cs Firestore implementation of IGrainStorage with lifecycle participation.
src/Google/Orleans.Persistence.GoogleFirestore/FirestoreStorageHostingExtensions.cs Hosting extensions to register Firestore grain storage provider.
src/Google/Orleans.Persistence.GoogleFirestore/FirestoreStateStorageOptions.cs Persistence options and configuration validator for Firestore storage.
src/Google/Orleans.GrainDirectory.GoogleFirestore/Orleans.GrainDirectory.GoogleFirestore.csproj New Firestore grain directory provider project packaging and dependencies.
src/Google/Orleans.GrainDirectory.GoogleFirestore/GrainDirectoryEntity.cs Firestore entity model for grain directory entries.
src/Google/Orleans.GrainDirectory.GoogleFirestore/GoogleFirestoreGrainDirectoryExtensions.cs Hosting extensions to register Firestore grain directory provider.
src/Google/Orleans.GrainDirectory.GoogleFirestore/GoogleFirestoreGrainDirectory.cs Firestore implementation of IGrainDirectory.
src/Google/Orleans.Clustering.GoogleFirestore/SiloInstanceEntity.cs Firestore entity model for membership entries.
src/Google/Orleans.Clustering.GoogleFirestore/OrleansSiloInstanceManager.cs Firestore membership table manager (version row, conditional updates, cleanup).
src/Google/Orleans.Clustering.GoogleFirestore/Orleans.Clustering.GoogleFirestore.csproj New Firestore clustering provider project packaging and dependencies.
src/Google/Orleans.Clustering.GoogleFirestore/MembershipEntity.cs Base membership entity model (cluster id + fields).
src/Google/Orleans.Clustering.GoogleFirestore/GoogleFirestoreMembershipTable.cs Firestore implementation of IMembershipTable.
src/Google/Orleans.Clustering.GoogleFirestore/GoogleFirestoreGatewayListProvider.cs Firestore implementation of IGatewayListProvider.
src/Google/Orleans.Clustering.GoogleFirestore/GoogleFirestoreClusteringExtensions.cs Hosting extensions to register Firestore clustering provider.
src/Google/Orleans.Clustering.GoogleFirestore/ClusterVersionEntity.cs Firestore entity model for membership table version row.
Orleans.slnx Adds the new Google provider and test projects to the solution.
Directory.Packages.props Adds Firestore/Storage/PubSub package versions and updates PubSub version.
.github/workflows/ci.yml Adds a dedicated CI job to run Google provider tests with emulators.

Copilot's findings

Suppressed comments (2)

test/Extensions/Google.Tests/FirestoreDataManagerStressTest.cs:72

  • The final Task.WhenAll(promises) result is not awaited/observed, so outstanding upserts may still be running when the test logs completion (and failures can be missed).
    src/Google/Orleans.Reminders.GoogleFirestore/GoogleFirestoreReminderServiceExtensions.cs:80
  • The XML docs say "Azure Table Storage" but this overload configures the Google Firestore reminder service.
    /// <summary>
    /// Adds reminder storage backed by Azure Table Storage.
    /// </summary>
  • Files reviewed: 54/54 changed files
  • Comments generated: 13

Comment thread .github/workflows/ci.yml Resolved
Comment thread .github/workflows/ci.yml Resolved
Copilot AI review requested due to automatic review settings August 1, 2026 02:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (11)

test/Extensions/Google.Tests/FirestoreDataManagerStressTest.cs:63

  • Task.WhenAll(promises) is not awaited, so the batch can still be running (and exceptions can be dropped) when the test proceeds/finishes.
    src/Google/Shared/Storage/FirestoreDataManager.cs:260
  • This log statement is guarded by IsEnabled(LogLevel.Debug) but uses LogTrace, which will typically be disabled when Debug is enabled (min level Debug). As a result, the message will not be emitted.
                if (this.Logger.IsEnabled(LogLevel.Debug)) this.Logger.LogTrace("Entity {id} not found on collection {collection}", id, this._partition);

test/Extensions/Google.Tests/FirestoreDataManagerStressTest.cs:69

  • Final Task.WhenAll(promises) is not awaited, so the method can return before completing outstanding writes (and exceptions can be dropped).
    src/Google/Shared/Storage/FirestoreDataManager.cs:357
  • This log statement is guarded by IsEnabled(LogLevel.Debug) but uses LogTrace, so it will not be emitted when the minimum log level is Debug.
                if (this.Logger.IsEnabled(LogLevel.Debug)) this.Logger.LogTrace("No entities found on collection {collection}", this._partition);

src/Google/Orleans.Reminders.GoogleFirestore/Orleans.Reminders.GoogleFirestore.csproj:6

  • Package metadata refers to "Google Cloud Storage" even though this project is a Firestore-backed reminders provider. This is user-visible (NuGet) and should be corrected to Firestore.
    <PackageId>Microsoft.Orleans.Reminders.GoogleFirestore</PackageId>
    <Title>Microsoft Orleans Google Cloud Storage Reminders Provider</Title>
    <Description>Microsoft Orleans reminders provider backed by Google Cloud Storage</Description>
    <PackageTags>$(PackageTags) Google Cloud Storage</PackageTags>

src/Google/Orleans.GrainDirectory.GoogleFirestore/Orleans.GrainDirectory.GoogleFirestore.csproj:5

  • Spelling: "GrainD irectory" contains an unintended space.
    <Description>Microsoft Orleans GrainD irectory provider backed by Google Firestore</Description>

.github/workflows/ci.yml:1008

  • This job installs .NET SDKs 3.1 and 7.0, but the repo’s other CI jobs use global-json-file: global.json and the solution targets newer frameworks. As written, this job is likely to fail or use the wrong SDK.
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: |
          3.1.x
          7.0.x
    - name: Setup Google Emulators      

src/Google/Shared/Storage/FirestoreDataManager.cs:291

  • This log statement is guarded by IsEnabled(LogLevel.Debug) but uses LogTrace, so it will not be emitted when the minimum log level is Debug.

This issue also appears on line 357 of the same file.

                if (this.Logger.IsEnabled(LogLevel.Debug)) this.Logger.LogTrace("No entities found on collection {collection}", this._partition);

src/Google/Orleans.GrainDirectory.GoogleFirestore/GoogleFirestoreGrainDirectory.cs:67

  • Catching all RpcException here will hide non-contention failures (eg, Unavailable/PermissionDenied) and return potentially stale data from Lookup instead of surfacing the error. This should only fall back to Lookup for the expected create-contention case.
        catch (RpcException)
        {
            var result = await this.Lookup(address.GrainId);
            return result;
        }

src/Google/Orleans.Persistence.GoogleFirestore/FirestoreStateStorageOptions.cs:10

  • Grammar: "clears it's state" should use the possessive "its".
    /// Indicates if grain data should be deleted or reset to defaults when a grain clears it's state.

src/Google/Orleans.Persistence.GoogleFirestore/FirestoreStateStorageOptions.cs:46

  • FirestoreStateStorageOptions inherits FirestoreOptions (which already has Validate(...) including reserved-name checks), but this validator only checks for whitespace. This can allow invalid configuration through and fail later at runtime.
    public void ValidateConfiguration()
    {
        if (string.IsNullOrWhiteSpace(this.options.ProjectId))
            throw new OrleansConfigurationException(
                $"Configuration for GoogleFirestoreStorage {this.name} is invalid. {nameof(this.options.ProjectId)} is not valid.");

        if (string.IsNullOrWhiteSpace(this.options.RootCollectionName))
            throw new OrleansConfigurationException(
                $"Configuration for GoogleFirestoreStorage {this.name} is invalid. {nameof(this.options.RootCollectionName)} is not valid.");
    }
  • Files reviewed: 55/55 changed files
  • Comments generated: 0 new

Copilot AI review requested due to automatic review settings August 1, 2026 15:33
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants