Skip to content

[default values] Move read-bridge column-default ramp into OpenHouse - #674

Open
cbb330 wants to merge 7 commits into
chbush/read-bridge-decode-off-retry-pathfrom
chbush/read-bridge-policy-ramp
Open

[default values] Move read-bridge column-default ramp into OpenHouse#674
cbb330 wants to merge 7 commits into
chbush/read-bridge-decode-off-retry-pathfrom
chbush/read-bridge-policy-ramp

Conversation

@cbb330

@cbb330 cbb330 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Depends on #668 (stacked on #645).

Move column-default rollout policy into OpenHouse so a deployment only supplies the defaults themselves.

Concern Owner after this PR
Feature id, self-serve property, wire keys OpenHouse (ReadBridgeConfigResolver)
Per-table ramp / kill OpenHouse (TableFeatureToggle + table property)
“What are this table’s defaults?” Deployment (ColumnDefaultsSource, e.g. LI ASL)

Ids (one token, capability-scoped — not bare read-bridge):

  • Feature id: read-bridge.column-default
  • Self-serve property: read-bridge.column-default.enabled
  • Config prefix: openhouse.read-bridge.column-default.<fieldId>

Resolve flow

On get/create/update, withConfig calls ReadBridgeConfigResolver.resolve(tableDto):

  1. No source (ColumnDefaultsSource.NONE) → empty config, no HTS call
  2. Ramp off (property false, or HTS not ACTIVE, or HTS error) → empty config; source not consulted
  3. Ramp on → ask source → stamp openhouse.read-bridge.column-default.<fieldId> = <single-value-json>

Self-serve override (isFeatureActivatedWithOverride):

  • property true / false → table wins, HTS skipped
  • property absent → exact HTS lookup (databaseId, tableId, featureId)
  • unparseable property → fail closed (off)

Changes

  • Internal API Changes — ApiConfig wires resolver via ObjectProvider<ColumnDefaultsSource> (no @ConditionalOnMissingBean noop / no @Primary); resolve(TableDto) only
  • New Features — capability-specific ramp + self-serve *.enabled override; fail-open on toggle lookup errors
  • Refactoring — ColumnDefaultsSource is data-only; ramp is not the deployment’s job
  • Documentation — javadoc spells exact-match HTS (no glob * / * today) and when HTS is hit
  • Tests — ReadBridgeConfigResolverTest covers inert/no-source, fail-open, opt-in/out, empty source, stamp, handler config; ReadBridgeColumnDefaultE2ETest is HTTP create/get with a stub source (property / HTS / fail-closed)

Why these choices

  • Capability-scoped id — column defaults must ramp independently of future bridges (e.g. deletion vectors). Bare read-bridge / v3-read-bridge left free for a later superset.
  • ObjectProvider → NONE — avoids competing default beans when a deployment registers its source with @Bean.
  • Fail-open on HTS errors — safe here because not bridging = today’s NULL reads. Must not be copied to capabilities where skipping is incorrect.
  • No cluster kill-switch property — HTS row or table property is the switch (no redeploy).

Ops notes

  • HTS match is exact (databaseId, tableId, featureId) via BaseTableFeatureToggle. There is no glob * / * fleet rule yet; fleet ramp means per-table ACTIVE rows and/or the table property.
  • When read-bridge.column-default.enabled is absent, resolve can hit HouseTables on the read path. When the property is present, HTS is skipped.

Testing Done

  • Added new tests for the changes made.
  • Updated existing tests to reflect the changes made.
  • Local: ./gradlew :services:tables:test --tests '*ReadBridgeConfigResolverTest' --tests '*ReadBridgeColumnDefaultE2ETest'

Additional Information

  • Large PR broken into smaller PRs, and PR plan linked in the description.

Stack

  1. #645 — substrate (seam + encode + decode hook)
  2. #668 — mark bridge failures unrecoverable on Iceberg’s retry path
  3. This PR — policy / ramp in OpenHouse
  4. #675ReadBridge.apply client overlay

LI follow-ups (data-only source): #2204#2203

Rollback Plan

Revert this PR. Deployments without a ColumnDefaultsSource still stamp nothing. Toggle fail-open keeps reads at today’s NULL behavior if HTS is unhealthy.

@cbb330

cbb330 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Next in stack: #675 (ReadBridge.apply), based on this branch.

@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from e145421 to 72f4fa5 Compare August 12, 2026 02:24
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from 72f4fa5 to 1f23dad Compare August 12, 2026 04:55
@cbb330
cbb330 marked this pull request as ready for review August 12, 2026 05:34
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from 59b8423 to 33ddb7a Compare August 12, 2026 16:51
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from ab56db9 to d5faa07 Compare August 13, 2026 05:42
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from d5faa07 to b0fbf21 Compare August 13, 2026 06:10
e);
return Collections.emptyMap();
}
if (columnDefaults == null || columnDefaults.isEmpty()) {

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.

Why let column defults be nullable?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is a stub right now and will be changed in follow up PRs

cbb330 added 7 commits August 13, 2026 16:55
Keep the deployment-specific ColumnDefaultsSource optional and data-only;
OpenHouse owns the read-bridge.column-default feature id, self-serve
enabled property, and fail-open toggle lookup before asking for defaults.
Correct the self-service property name and drop the contradictory
"cluster kill switch" claim. Add coverage for a real source that returns
no defaults, and assert table-property opt-in never calls the server
toggle.

Testing Done:
- :services:tables:test --tests '*ReadBridgeConfigResolverTest'
BaseTableFeatureToggle looks up (databaseId, tableId, featureId) exactly;
claiming a * / * fleet kill switch was inaccurate. Also note HTS is only
hit when the self-service property is absent.
Replace essay javadoc with brief ownership, contract, ObjectProvider,
and fail-open notes so the PR description carries the design narrative.
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