Add Core Cache API Support
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start with stubs/wit_world/imports/cache.py and compare the proposed wrapper with the existing KV Store streaming integration. Verify hostcall invocation, option and state-flag mapping, error handling, context-manager transactions, and IOBase-compatible body streaming; done means wrapper-focused tests cover these behaviors without testing Viceroy cache persistence.
Written by the indexing model from the issue text.
Description
Overview
Add support for Fastly's Core Cache API, providing advanced caching capabilities with request collapsing, stale-while-revalidate, and streaming.
WIT Interface
interface cache {
use types.{error};
use http-body.{body};
use http-req.{request};
use async-io.{pollable as pending-entry};
resource entry {
lookup: static func(key: list<u8>, options: lookup-options) -> result<entry, error>;
transaction-lookup: static func(key: list<u8>, options: lookup-options) -> result<entry, error>;
transaction-lookup-async: static func(key: list<u8>, options: lookup-options) -> result<pending-entry, error>;
transaction-insert: func(options: write-options) -> result<body, error>;
transaction-insert-and-stream-back: func(options: write-options) -> result<tuple<body, entry>, error>;
transaction-update: func(options: write-options) -> result<_, error>;
get-state: func() -> result<lookup-state, error>;
get-user-metadata: func(max-len: u64) -> result<option<list<u8>>, error>;
get-body: func(options: get-body-options) -> result<body, error>;
get-length: func() -> result<option<object-length>, error>;
get-max-age-ns: func() -> result<option<duration-ns>, error>;
get-stale-while-revalidate-ns: func() -> result<option<duration-ns>, error>;
get-age-ns: func() -> result<option<duration-ns>, error>;
get-hits: func() -> result<option<cache-hit-count>, error>;
transaction-cancel: func() -> result<_, error>;
}
resource replace-entry {
replace: static func(key: list<u8>, options: replace-options) -> result<replace-entry, error>;
get-age-ns: func() -> result<option<duration-ns>, error>;
get-body: func(options: get-body-options) -> result<option<body>, error>;
get-hits: func() -> result<option<cache-hit-count>, error>;
get-length: func() -> result<option<object-length>, error>;
get-max-age-ns: func() -> result<option<duration-ns>, error>;
get-stale-while-revalidate-ns: func() -> result<option<duration-ns>, error>;
get-state: func() -> result<option<lookup-state>, error>;
get-user-metadata: func(max-len: u64) -> result<option<list<u8>>, error>;
}
type object-length = u64;
type duration-ns = u64;
type cache-hit-count = u64;
resource extra-lookup-options {
constructor();
}
record lookup-options {
request-headers: option<borrow<request>>,
always-use-requested-range: bool,
extra: option<borrow<extra-lookup-options>>,
}
resource extra-write-options {
constructor();
}
record write-options {
max-age-ns: duration-ns,
request-headers: option<borrow<request>>,
vary-rule: option<string>,
initial-age-ns: option<duration-ns>,
stale-while-revalidate-ns: option<duration-ns>,
surrogate-keys: option<string>,
length: option<object-length>,
user-metadata: option<list<u8>>,
edge-max-age-ns: option<duration-ns>,
sensitive-data: bool,
extra: option<borrow<extra-write-options>>,
}
resource extra-get-body-options;
record get-body-options {
%from: option<u64>,
to: option<u64>,
extra: option<borrow<extra-get-body-options>>,
}
flags lookup-state {
found,
usable,
stale,
must-insert-or-update,
usable-if-error,
}
resource extra-replace-options {
constructor();
}
enum replace-strategy {
immediate,
immediate-force-miss,
wait,
}
record replace-options {
request-headers: option<borrow<request>>,
replace-strategy: option<replace-strategy>,
always-use-requested-range: bool,
extra: option<borrow<extra-replace-options>>,
}
insert: func(key: list<u8>, options: write-options) -> result<body, error>;
await-entry: func(handle: pending-entry) -> result<entry, error>;
close-pending-entry: func(handle: pending-entry) -> result<_, error>;
close-entry: func(handle: entry) -> result<_, error>;
replace-insert: func(handle: replace-entry, options: write-options) -> result<body, error>;
close-replace-entry: func(handle: replace-entry) -> result<_, error>;
}
WIT bindings: stubs/wit_world/imports/cache.py
API Design
- Implement
CacheEntryresource wrapper for cache operations - Support lookup and transaction-based caching patterns
- Implement
LookupOptionsandWriteOptionsdataclasses - Provide access to cache metadata: age, TTL, hits, state flags
- Transaction methods:
transaction_lookup(),insert(),update(),cancel() - Entry body should implement
io.IOBasefor streaming (similar to KV Store) get_body()returns file-like object that can be read in chunks or passed to stdlib functions
Cross-SDK Comparison: All SDKs provide lookup(), insert(), transaction_lookup() with similar semantics. Rust uses strong typing for state/options enums, Go uses simple structs, JS uses async/Promise-based API. Python should support both blocking operations and context managers for transactions.
Viceroy Testing
Viceroy's cache implementation is limited/stubbed. Testing focus should be on:
- Verifying hostcall invocations work correctly
- Testing SDK wrapper logic (option parsing, state flag handling, error mapping)
- Ensuring body streaming integration functions properly
Do NOT:
- Try to verify actual cache persistence behavior
- Create elaborate tests around Viceroy's stubbed functionality
- Test cache hit/miss logic (this is host behavior, not SDK code)
The goal is to verify our Python wrapper code works, not to test Viceroy's cache implementation.
Reference
- Dominant language
- Python
- Stars
- 5
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fastly/compute-sdk-python
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
fastly/compute-sdk-python#116 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
fastly/compute-sdk-python#98 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
fastly/compute-sdk-python#74 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
fastly/compute-sdk-python#61 ·
-
fastly/compute-sdk-python#60 · 1 assignee ·
All issues in fastly/compute-sdk-python
Similar issues
-
essnmx good first issue
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
[Feature] 奇物选择添加优先级 Open
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
syfoud/Simulated_Scepter#174 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Giskard-AI/giskard-oss#2840 · 1 comment ·
-
A claim comment carrying the issue number is silently declined while the workflow reports success Openarea: repo bug perceived difficulty: 2
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
yeti-platform/yeti#1380 ·