Skip to content

feat: support freshness-aware table loading in RestCatalog - #4094

Open
YuangGao wants to merge 4 commits into
apache:mainfrom
YuangGao:feat/rest-freshness-aware-load
Open

YuangGao wants to merge 4 commits into
apache:mainfrom
YuangGao:feat/rest-freshness-aware-load

Conversation

@YuangGao

@YuangGao YuangGao commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Closes #4075

Rationale for this change

  • load_table never sent If-None-Match, and a body-less 304 failed to parse.
  • Tables loaded with an ETag are now cached; a later load sends If-None-Match and returns a fresh Table from the cached response on 304.

Are these changes tested?

  • test_rest.py — reuse on 304, 304 without a cached table, and max-entries=0.
  • test_rest_catalog.py — 200 then 304 against the REST fixture.

Are there any user-facing changes?

  • New catalog properties rest-table-cache.max-entries (default 100, 0 disables) and rest-table-cache.expire-after-write-ms (default 5 minutes).

@YuangGao

Copy link
Copy Markdown
Contributor Author

@Fokko @rambleraptor could you take a look when you have a moment? this adds ETag-based table caching to RestCatalog, matching Java's rest-table-cache properties.

@YuangGao

Copy link
Copy Markdown
Contributor Author

@Fokko rebased onto main after #4310, could you take a look when you have a moment?

@YuangGao
YuangGao force-pushed the feat/rest-freshness-aware-load branch from 546bca0 to 09cf09a Compare November 11, 2026 05:05

@rambleraptor rambleraptor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Adding the lock prevents us from pickling. Thanks for the contribution!

if ttl_ms <= 0:
raise ValueError(f"Invalid value for {REST_TABLE_CACHE_EXPIRE_AFTER_WRITE_MS}: {ttl_ms} (must be positive)")
self._table_cache = TTLCache(maxsize=max_entries, ttl=ttl_ms / 1000) if max_entries > 0 else None
self._table_cache_lock = threading.Lock()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This prevents the table from being pickled.

Comment thread pyiceberg/catalog/rest/__init__.py Outdated
def _is_short_lived_credential(key: str) -> bool:
"""Whether a loadTable config key carries a short-lived storage credential."""
key = key.lower()
return key in (S3_SESSION_TOKEN, GCS_TOKEN) or key.startswith(ADLS_SAS_TOKEN)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we need to add client.session-token, adls.token and token here as well.

@YuangGao

YuangGao commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor Author

@rambleraptor updated, thanks!

This branch has not been deployed

No deployments
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.

RestCatalog: support freshness-aware table loading (If-None-Match / 304 Not Modified), as Iceberg Java does

2 participants