Benjamin commit on credits ran out

This commit is contained in:
bterkuile committed 2026-07-06 19:06:59 -05:00
1 parent 37288db487
commit 185ca0ca17
3 files changed
+203 -9

No files matched your search

+33 -9
View File
@@ -70,11 +70,16 @@ SimplyBased::Lock.new.with_lock("rebuild", ttl: 30) do
end
```
- **Counter** — Couchbase binary increment/decrement (true atomic counters).
- **Counter** — Couchbase binary increment/decrement (true atomic counters),
with Redis INCR/INCRBY semantics: the first increment of a missing key
returns the delta. One divergence: Couchbase counters are unsigned, so
decrement clamps at 0 instead of going negative.
- **Cache** — an `ActiveSupport::Cache::Store` over KV + native TTL; drop-in for
`Rails.cache` and therefore ActiveJob.
- **Lock** — distributed lock: insert-if-absent + TTL auto-expiry + CAS-checked
release so only the holder can unlock.
`Rails.cache` and therefore ActiveJob. (`clear` is a no-op — entries expire
via TTL.)
- **Lock** — distributed lock: insert-if-absent + mandatory TTL auto-expiry +
CAS-checked release, so only the holder can unlock (`force_release!` is the
explicit override) and a crashed holder can never leave an immortal lock.
## The one recommended pattern shift
@@ -85,22 +90,41 @@ Couchbase **Collection** — tighter GSIs, cleaner queries, idiomatic Couchbase.
## Status & test coverage
SimplyBased runs the **simply_couch test suite** against a live Couchbase.
SimplyBased runs the **simply_couch test suite** (plus its own additions)
against a live Couchbase. See `SIMPLY_BASED_REVIEW.md` for the full
independent review this status section is based on.
- **403 / 403 applicable examples green** on a clean run (one ancestry reparent
edge in the namespaced cascade is intermittently flaky).
- **Green:** CRUD, finders (`find`, `all`, `first`, `find_by_*`, `count_by_*`),
`belongs_to` / `has_many` / `has_one` / `has_and_belongs_to_many`, validations,
callbacks, dirty tracking, soft-delete (incl. soft-delete-aware finders),
pagination, bulk, eager-loading, **ancestry / trees**, and the Redis primitives.
pagination, bulk (true batched KV multi-ops), eager-loading, embedded documents
(`has_many_embedded` / `is_embedded_in`, minus reverse lookups),
**ancestry / trees**, the Redis primitives, adapter-contract shared examples,
and multi-threaded concurrency examples (CAS conflicts, atomic counters,
lock mutual exclusion).
- **Ancestry** is a materialized path (`path_ids`, root→self): children =
`path_ids[len-2] = $id`, subtree = `$id IN path_ids`, roots =
`ARRAY_LENGTH(path_ids) = 1` — plain N1QL, no recursive view build.
- **Views that cannot translate to N1QL raise `SimplyBased::UnsupportedView`**
at query time (`:conditions` JS fragments, `:emit_value`, list functions)
instead of silently returning unfiltered results.
- **Excluded by design:**
- `:couchdb_only` specs — native inline attachments, JS-view token-safety,
design-document maintenance, raw custom JS views: no Couchbase equivalent
(use `has_s3_attached` / `has_local_attached`; N1QL uses bound parameters).
- `embedded_in` reverse-lookups — out of scope for this gem.
- `embedded_in` reverse-lookups (`:embedded_in_reverse_lookup`) — querying a
foreign key stored *inside* an embedded array element would need an
UNNEST-based query path; not implemented.
### Known gaps (unchanged, deliberate)
- **No multi-document transactions** — single-document atomicity + CAS only.
Couchbase's SDK has transactions; this ORM does not surface them.
- **No index-migration framework** — GSIs are created lazily per association;
ad-hoc queries need deliberately designed indexes or they fall back to a
primary scan (a warning is emitted when lazy index creation fails).
- `Cache#clear` is a no-op (namespaced clear would need a key scan); entries
expire via their TTLs.
```bash
docker run -d --name cb -p 8091-8096:8091-8096 -p 11210:11210 couchbase:community