Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
4477bc9
feat(runtime): isolate opt-in dissemination on merged lifecycle baseline
ReubenBond Sep 11, 2026
7e185b9
test(dissemination): preserve current real-process and cost evidence
ReubenBond Sep 11, 2026
67a6f92
test(dissemination): isolate current convergence regressions
ReubenBond Sep 11, 2026
9bf3fb3
chore(api): capture generated dissemination surfaces
ReubenBond Sep 11, 2026
7b3eac9
fix(dissemination): preserve publication and lifecycle guarantees
ReubenBond Sep 13, 2026
0e87e3b
fix(dissemination): bound receive work and application lifetimes
ReubenBond Sep 13, 2026
5c3bc39
style(dissemination): align receive cursor label formatting
ReubenBond Sep 13, 2026
b596512
fix(dissemination): preserve completed application outcomes
ReubenBond Sep 13, 2026
111031b
fix(dissemination): preserve caller cancellation identity
ReubenBond Sep 13, 2026
7044bbf
perf(dissemination): reuse active status lookup for cache pruning
ReubenBond Sep 14, 2026
5efb385
test(dissemination): assert silo key type when sorting digests
ReubenBond Sep 14, 2026
0570152
fix(dissemination): converge same-version inventory cleanup
ReubenBond Sep 15, 2026
109ed45
test(dissemination): own measurement abort lifetime
ReubenBond Sep 15, 2026
b3cfc15
test(dissemination): await deadline requeue before shutdown
ReubenBond Sep 15, 2026
64ed12b
fix(dissemination): enforce membership and completion invariants
ReubenBond Sep 15, 2026
ffd2b82
test(dissemination): isolate history-miss repair provenance
ReubenBond Sep 15, 2026
09ebf2e
fix(dissemination): refresh topology after same-version cleanup
ReubenBond Sep 15, 2026
606c4b7
test(dissemination): temporarily enable defaults for CI exposure
ReubenBond Sep 15, 2026
97cfeb1
fix(dissemination): drain protocol operations with shared admission gate
ReubenBond Sep 15, 2026
15a5008
perf(dissemination): reduce load propagation delays and allocation
ReubenBond Sep 15, 2026
92a231f
test(dissemination): compare off-on scaling through 100 silos
ReubenBond Sep 15, 2026
36ccad1
perf(dissemination): compact acknowledgments and reuse pruning inventory
ReubenBond Sep 15, 2026
fa28ac1
test(dissemination): assert decoded acknowledgment types
ReubenBond Sep 16, 2026
5c05b94
test(dissemination): include compact acknowledgment in wire contract
ReubenBond Sep 16, 2026
ab21609
test(dissemination): bound pruning scratch allocations
ReubenBond Sep 16, 2026
3e2fcef
perf(dissemination): aggregate load updates on a parent-child tree
ReubenBond Sep 16, 2026
854b9cc
test(dissemination): implement updated membership refresh contract
ReubenBond Sep 16, 2026
0d7fe8e
test(dissemination): iterate aggregation nodes portably
ReubenBond Sep 16, 2026
896d415
test(dissemination): record custom aggregation transport sends
ReubenBond Sep 16, 2026
fdb7533
perf(runtime): batch load updates only at the aggregation root
ReubenBond Sep 16, 2026
258a730
refactor(dissemination): simplify routing and queue notification state
ReubenBond Sep 16, 2026
c04daf3
test(dissemination): retain focused compatibility CI and extract meas…
ReubenBond Sep 16, 2026
b6ae361
fix(dissemination): fence membership reset state and preserve recovery
ReubenBond Sep 16, 2026
144120b
test(dissemination): align fixtures with explicit opt-in and owner state
ReubenBond Sep 16, 2026
db36740
fix(dissemination): validate older full values and isolate metrics
ReubenBond Sep 16, 2026
e958c36
style(dissemination): format metric boundary regression cases
ReubenBond Sep 16, 2026
4acf6f3
fix(membership): stop invalidated development table incarnations
ReubenBond Sep 16, 2026
15ee078
perf(dissemination): pace root microbatches and bound maintenance work
ReubenBond Sep 16, 2026
baf402e
test(dissemination): preserve sequential harness execution on xUnit 4
ReubenBond Sep 16, 2026
2b13acc
perf(dissemination): synchronize load publication with cohort receipts
ReubenBond Sep 17, 2026
268ee7e
fix(dissemination): preserve native publication completion during can…
ReubenBond Sep 17, 2026
6024ad1
refactor(dissemination): specialize repair and scheduling for runtime…
ReubenBond Sep 17, 2026
4096c5a
fix(dissemination): consume wake signals with captured work
ReubenBond Sep 17, 2026
3435701
test(dissemination): release deferred regression continuations
ReubenBond Sep 17, 2026
728523a
test(dissemination): bound the retry observer wait
ReubenBond Sep 17, 2026
02e4326
feat(dissemination): broadcast sparse membership deltas
ReubenBond Sep 17, 2026
4f77c61
fix(dissemination): preserve canonical views and Dead-row pruning
ReubenBond Sep 17, 2026
285bd5d
test(dissemination): assert retained-row acknowledgment rejection
ReubenBond Sep 17, 2026
3bf682c
refactor(dissemination): rely on merged membership lifetime policy
ReubenBond Sep 17, 2026
b496bbb
test(dissemination): isolate broadcast failure metric injection
ReubenBond Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/scripts/dissemination-compatibility.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
[CmdletBinding()]
param(
[string] $BaselineDirectory = '.dissemination-baseline',
[string] $ArtifactsDirectory = 'Artifacts/DisseminationCompatibility',
[switch] $SkipBuild
)

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
$baselineSha = '6739589254b746a8790cf53524e6abe372bb53d4'
$root = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
$artifacts = [System.IO.Path]::GetFullPath((Join-Path $root $ArtifactsDirectory))
$binaries = Join-Path $artifacts 'bin'
$results = Join-Path $artifacts 'results'
New-Item -ItemType Directory -Force $binaries, $results | Out-Null

function Invoke-DotNet([string[]] $Arguments) {
& dotnet @Arguments
if ($LASTEXITCODE -ne 0) {
throw "dotnet failed ($LASTEXITCODE): $($Arguments -join ' ')"
}
}

function Get-Revision([string] $Directory) {
$revision = & git -C $Directory rev-parse HEAD
if ($LASTEXITCODE -ne 0) {
throw "Not a source checkout: $Directory"
}
return $revision.Trim()
}

function Publish-Silo([string] $Checkout, [string] $Runtime, [string] $Revision) {
$project = Join-Path $Checkout 'test/Dissemination.IntegrationHarness/Silo/Dissemination.Silo.csproj'
$output = Join-Path $binaries $Runtime
Invoke-DotNet @(
'publish', $project, '--configuration', 'Release', '--framework', 'net10.0',
'--output', $output, '--verbosity', 'minimal',
"-p:HarnessRuntime=$Runtime", "-p:SourceRevisionId=$Revision",
'-p:OfficialBuild=true', "-p:BUILD_SOURCEVERSION=$Revision",
"-bl:$(Join-Path $artifacts "build-$Runtime.binlog")"
)
$assemblyPath = Join-Path $output 'Orleans.Runtime.dll'
$identity = [System.Reflection.AssemblyName]::GetAssemblyName($assemblyPath)
$assemblies = @{}
foreach ($file in Get-ChildItem -LiteralPath $output -Filter 'Orleans*.dll' -File) {
$name = [System.Reflection.AssemblyName]::GetAssemblyName($file.FullName)
$assemblies[$name.Name] = @{
AssemblyVersion = $name.Version.ToString()
Sha256 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash
}
}
@{
Runtime = $Runtime
SourceRevision = $Revision
AssemblyName = $identity.Name
AssemblyVersion = $identity.Version.ToString()
Sha256 = (Get-FileHash -LiteralPath $assemblyPath -Algorithm SHA256).Hash
Assemblies = $assemblies
} | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $output 'manifest.json')
}

if (!$SkipBuild) {
if ($env:GITHUB_ACTIONS -ne 'true') {
throw 'Building the pinned baseline is CI-only. Download the workflow binary artifact and use -SkipBuild for explicit local reproduction.'
}

$baseline = [System.IO.Path]::GetFullPath((Join-Path $root $BaselineDirectory))
if ($baseline -eq $root) {
throw 'The baseline must not be the feature checkout.'
}
$baselineTopLevel = (& git -C $baseline rev-parse --show-toplevel)
if ($LASTEXITCODE -ne 0 -or [System.IO.Path]::GetFullPath($baselineTopLevel.Trim()) -ne $baseline) {
throw 'The baseline must have its own isolated git checkout, not merely a directory in the feature checkout.'
}
if ((Get-Revision $baseline) -ne $baselineSha) {
throw "Baseline must be pinned to $baselineSha."
}
$sourceChanges = & git -C $baseline status --porcelain --untracked-files=all -- src
if ($LASTEXITCODE -ne 0 -or $sourceChanges) {
throw 'Pinned baseline runtime sources have local modifications.'
}
if (Test-Path -LiteralPath (Join-Path $baseline 'src/Orleans.Runtime/Dissemination')) {
throw 'The pinned baseline unexpectedly contains the new dissemination implementation.'
}

# Only the test executable is copied. Every Orleans source project resolves inside its own checkout.
$harnessSource = Join-Path $root 'test/Dissemination.IntegrationHarness'
$harnessDestination = Join-Path $baseline 'test/Dissemination.IntegrationHarness'
if (Test-Path -LiteralPath $harnessDestination) {
throw "Refusing to overwrite an existing baseline harness: $harnessDestination"
}
New-Item -ItemType Directory -Force $harnessDestination | Out-Null
foreach ($part in @('Silo', 'Shared')) {
New-Item -ItemType Directory -Force (Join-Path $harnessDestination $part) | Out-Null
Get-ChildItem -LiteralPath (Join-Path $harnessSource $part) -File |
Where-Object { $_.Extension -in '.cs', '.csproj' } |
Copy-Item -Destination (Join-Path $harnessDestination $part)
}

Publish-Silo $baseline 'Old' $baselineSha
Publish-Silo $root 'New' (Get-Revision $root)
Invoke-DotNet @(
'publish', (Join-Path $root 'test/Dissemination.IntegrationHarness/Tests/Dissemination.IntegrationHarness.Tests.csproj'),
'--configuration', 'Release', '--framework', 'net10.0',
'--output', (Join-Path $binaries 'Runner'), '--verbosity', 'minimal',
"-bl:$(Join-Path $artifacts 'build-runner.binlog')"
)
}

$env:ORLEANS_DISSEMINATION_OLD = Join-Path $binaries 'Old'
$env:ORLEANS_DISSEMINATION_NEW = Join-Path $binaries 'New'
$env:ORLEANS_DISSEMINATION_RESULTS = $results
$runner = Join-Path $binaries 'Runner/Dissemination.IntegrationHarness.Tests.dll'
if (!(Test-Path -LiteralPath $runner)) {
throw "Published runner not found: $runner"
}
$testClass = 'Orleans.Dissemination.IntegrationHarness.VersionSkewTests'
$minimum = '10'

@{
PinnedBaseline = $baselineSha
CurrentCommit = Get-Revision $root
StartUtc = [DateTimeOffset]::UtcNow
Command = "dotnet $runner --filter-class $testClass --minimum-expected-tests $minimum --report-trx"
Environment = 'Separate loopback OS processes with a controlled test membership provider.'
} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $results 'invocation.json')

Push-Location $root
try {
Invoke-DotNet @(
$runner, '--filter-class', 'Orleans.Dissemination.IntegrationHarness.CompatibilityHarnessTests',
'--minimum-expected-tests', '8', '--report-trx',
'--results-directory', (Join-Path $results 'harness-checks')
)

Invoke-DotNet @(
$runner, '--filter-class', $testClass, '--minimum-expected-tests', $minimum,
'--report-trx', '--results-directory', $results
)
}
finally {
Pop-Location
}
78 changes: 78 additions & 0 deletions .github/workflows/dissemination-compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Dissemination compatibility

on:
pull_request:
branches: [main]
paths:
- '.github/workflows/dissemination-compatibility.yml'
- '.github/scripts/dissemination-compatibility.ps1'
- 'test/Dissemination.IntegrationHarness/**'
- 'src/Orleans.Core.Abstractions/IDs/SiloAddress.cs'
- 'src/Orleans.Runtime/Dissemination/**'
- 'src/Orleans.Runtime/MembershipService/**'
- 'src/Orleans.Runtime/Placement/DeploymentLoadPublisher.cs'
- 'src/Orleans.Runtime/Configuration/Options/DeploymentLoadPublisherOptions.cs'
- 'src/Orleans.Runtime/Configuration/Options/DisseminationOptionsValidator.cs'
- 'src/Orleans.Runtime/Hosting/DefaultSiloServices.cs'
- 'src/Orleans.Runtime/OrleansContracts.txt'
- 'src/Orleans.Core/OrleansContracts.txt'
- 'src/Orleans.Core/Runtime/Constants.cs'
- 'src/Orleans.Core/Runtime/MembershipTableSnapshot.cs'
- 'src/Orleans.Core/SystemTargetInterfaces/IDisseminationSystemTarget.cs'
- 'src/Orleans.Core/SystemTargetInterfaces/IDeploymentLoadPublisher.cs'
- 'src/Orleans.Core/SystemTargetInterfaces/IMembershipTable.cs'
- 'src/Orleans.Core/Configuration/Options/ClusterMembershipOptions.cs'
- 'src/Orleans.Core/Configuration/Options/DisseminationOptions.cs'
merge_group:
types: [checks_requested]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: dissemination-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_NOLOGO: true

jobs:
version-skew:
name: Pinned-binary upgrade, rollback and recovery
runs-on: ubuntu-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- name: Isolated pre-dissemination checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: dotnet/orleans
ref: 6739589254b746a8790cf53524e6abe372bb53d4
path: .dissemination-baseline
persist-credentials: false
- uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5
with:
global-json-file: global.json
- name: Build isolated binaries and run bounded merge-gate checks
shell: pwsh
run: ./.github/scripts/dissemination-compatibility.ps1
- name: Preserve test results and process diagnostics
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: dissemination-compatibility-results
retention-days: 14
path: |
Artifacts/DisseminationCompatibility/results
Artifacts/DisseminationCompatibility/*.binlog
- name: Preserve reproducible binary pair
if: success()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: dissemination-compatibility-binaries
retention-days: 7
path: Artifacts/DisseminationCompatibility/bin
3 changes: 2 additions & 1 deletion docs/site/src/content/docs/host/monitoring/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Orleans observability
description: Configure OpenTelemetry logging, metrics, and tracing for Orleans.
ms.date: 08/02/2026
ms.date: 09/04/2026
ms.topic: overview
---

Expand Down Expand Up @@ -79,6 +79,7 @@ The example's 10% head-sampling ratio is a starting point, not a universal produ
## Next steps

- [Monitor Orleans metrics](metrics.md)
- [Monitor runtime dissemination](runtime-dissemination.md)
- [Interpret Orleans signals](signals.md)
- [Troubleshoot Orleans incidents](troubleshooting.md)
- [Secure and operate the Orleans Dashboard](../../dashboard/index.md)
25 changes: 24 additions & 1 deletion docs/site/src/content/docs/host/monitoring/metrics-catalog.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Orleans metrics catalog
description: Complete reference for metrics emitted by the Microsoft.Orleans meter.
ms.date: 08/18/2026
ms.date: 09/04/2026
ms.topic: reference
---

Expand Down Expand Up @@ -65,6 +65,29 @@ Request latency covers the interval until the caller's callback completes, inclu

`Destination` and `silo` contain silo addresses and incarnations. They are useful during incident diagnosis and can create new time series during restarts.

## Runtime dissemination

| Instrument | Type | Unit | Attributes | Description |
|---|---|---|---|---|
| `orleans-dissemination-anti-entropy-digests` | C | `digests` | `direction` | Digest entries sent in successful outbound exchanges or received in inbound exchanges. |
| `orleans-dissemination-anti-entropy-exchanges` | C | `operations` | `direction`, `truncated` | Successful anti-entropy requests and responses. `truncated=true` indicates that response budgets left candidates for a later exchange. |
| `orleans-dissemination-anti-entropy-failures` | C | `operations` | `reason` | Outbound anti-entropy peer operations which ended in `timeout` or `error`. |
| `orleans-dissemination-anti-entropy-values` | C | `values` | `direction` | Repair values returned by successful anti-entropy exchanges. |
| `orleans-dissemination-broadcast-received` | C | `messages` | `namespace`, `kind` | Broadcast batches received, counted once for each namespace represented in the batch. |
| `orleans-dissemination-broadcast-scheduled` | C | `schedules` | `reason` | Per-peer pump schedules split into `immediate` and `retry`. |
| `orleans-dissemination-broadcast-send-failures` | C | `attempts` | `reason` | Broadcast send attempts which ended in `timeout` or `error`. |
| `orleans-dissemination-broadcast-sent` | C | `messages` | `namespace`, `kind` | Successfully completed broadcast sends, counted once for each namespace represented in the batch. |
| `orleans-dissemination-bytes-sent` | C | `bytes` | `namespace`, `kind` | Serialized dissemination payload bytes in successful broadcasts. |
| `orleans-dissemination-payload-dropped` | C | `values` | `namespace`, `reason` | Values rejected by a payload guard. |
| `orleans-dissemination-pump-failures` | C | `failures` | `status` | Unexpected peer-pump failures split into `recovered` and `permanent`. |
| `orleans-dissemination-publications` | C | `operations` | `namespace`, `result`, `reason` | Publication attempts classified as `accepted` or `rejected`. Rejection reasons identify disabled namespaces, unavailable membership or values, invalid versions or repairs, and over-budget repairs. |
| `orleans-dissemination-queue-admission-rejected` | C | `keys` | `namespace`, `reason` | New distinct keys rejected after a namespace reached its per-peer pending-key limit. |
| `orleans-dissemination-values-applied` | C | `values` | `namespace`, `result` | Received values classified by the namespace apply result. |
| `orleans-dissemination-values-received` | C | `values` | `namespace`, `kind` | Values included in received broadcast batches before individual application. |
| `orleans-dissemination-values-sent` | C | `values` | `namespace`, `kind` | Values included in successfully completed broadcast sends. |

All dissemination attributes have bounded runtime-defined values. Keys and peer addresses are available through opt-in diagnostic events instead of metric attributes. See [Monitor runtime dissemination](runtime-dissemination.md).

## Scheduling, activations, and grains

| Instrument | Type | Unit | Attributes | Description |
Expand Down
Loading
Loading