Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
402 commits
Select commit Hold shift + click to select a range
1b4675d
Merge remote-tracking branch 'origin/master'
adranwit Feb 24, 2026
1d68a32
shape/compile: add type support helpers; refine preprocessing and typ…
adranwit Feb 24, 2026
7abce12
shape/compile: add type support helpers; refine preprocessing and typ…
adranwit Feb 24, 2026
022ef9c
updated dep
adranwit Feb 24, 2026
6f552ce
updated dep
adranwit Feb 24, 2026
6fc7357
updated dep
adranwit Feb 24, 2026
7e8970b
updated dep
adranwit Feb 24, 2026
6ca1923
updated dep
adranwit Feb 25, 2026
66f763f
patched async jobs, enhanced dql grammar
adranwit Feb 25, 2026
3aae6be
patched async jobs, enhanced dql grammar
adranwit Feb 25, 2026
e5536e0
refactor openapi schema/generator and add polymorphism scaffolding
adranwit Feb 25, 2026
4eea356
harden openapi responses typing and marshal/session compatibility
adranwit Feb 25, 2026
286a88f
updated openapi schema builder
adranwit Feb 25, 2026
74fd475
updated openapi schema builder
adranwit Feb 25, 2026
b1f84f3
updated openapi schema builder
adranwit Feb 25, 2026
1da05d0
updated openapi schema builder
adranwit Feb 26, 2026
055ee4b
updated openapi schema builder
adranwit Feb 26, 2026
8d10d62
- stabilize e2e
adranwit Feb 27, 2026
85f81b5
- stabilize e2e
adranwit Feb 27, 2026
1cbc10f
- stabilize e2e
adranwit Feb 27, 2026
0da955e
patched selector, column discovery
adranwit Mar 2, 2026
84e5773
enhanced shape
adranwit Mar 5, 2026
d4f6192
enhanced shape
adranwit Mar 7, 2026
e71fbd9
added dynamic grouping
adranwit Mar 7, 2026
cbe966f
added dynamic grouping
adranwit Mar 9, 2026
c9eee5c
added dynamic grouping
adranwit Mar 9, 2026
2861f7b
added dynamic grouping
adranwit Mar 9, 2026
d66bd81
added dynamic grouping
adranwit Mar 9, 2026
de7e44b
added dynamic grouping
adranwit Mar 9, 2026
0267fc5
added dynamic grouping
adranwit Mar 9, 2026
a3e90a9
added dynamic grouping
adranwit Mar 9, 2026
07f2671
added dynamic grouping
adranwit Mar 9, 2026
c7b4ee5
added dynamic grouping
adranwit Mar 9, 2026
faef131
added dynamic grouping
adranwit Mar 9, 2026
a695e25
added dynamic grouping
adranwit Mar 9, 2026
22e0d0b
added dynamic grouping
adranwit Mar 9, 2026
1c730fb
added dynamic grouping
adranwit Mar 9, 2026
271cfe1
added dynamic grouping
adranwit Mar 9, 2026
c3d2b87
added dynamic grouping
adranwit Mar 9, 2026
bcd0f0c
added dynamic grouping
adranwit Mar 9, 2026
e78ea4f
added dynamic grouping
adranwit Mar 9, 2026
674161f
added dynamic grouping
adranwit Mar 9, 2026
de43b73
added dynamic grouping
adranwit Mar 9, 2026
400996b
added dynamic grouping
adranwit Mar 9, 2026
6b9107f
added dynamic grouping
adranwit Mar 9, 2026
92d6daa
added dynamic grouping
adranwit Mar 9, 2026
a53544e
added dynamic grouping
adranwit Mar 9, 2026
2e260fe
added dynamic grouping
adranwit Mar 9, 2026
5c3592a
added dynamic grouping
adranwit Mar 9, 2026
40242c5
added dynamic grouping
adranwit Mar 9, 2026
d97fdfe
added dynamic grouping
adranwit Mar 9, 2026
13eb671
added dynamic grouping
adranwit Mar 9, 2026
944dd93
added dynamic grouping
adranwit Mar 9, 2026
5995d62
added dynamic grouping
adranwit Mar 9, 2026
471bc9a
added dynamic grouping
adranwit Mar 9, 2026
66521bc
added dynamic grouping
adranwit Mar 9, 2026
3944782
added dynamic grouping
adranwit Mar 9, 2026
1ee2493
added dynamic grouping
adranwit Mar 9, 2026
8bdde2b
added dynamic grouping
adranwit Mar 9, 2026
324a597
added dynamic grouping
adranwit Mar 9, 2026
a9e233d
extended grouping e2e
adranwit Mar 10, 2026
1308c34
enhanced grouping
adranwit Mar 10, 2026
d9303b2
Merge pull request #69 from viant/shape && grouping
adranwit Mar 10, 2026
a75e070
enhanced grouping
adranwit Mar 10, 2026
fdefc1a
enhanced grouping
adranwit Mar 10, 2026
8c91587
Merge pull request #70 from viant/shape
adranwit Mar 10, 2026
14bdea9
- reporting enhancement
adranwit Mar 14, 2026
03e2576
fixed ReverseReplace incorrect substitution when one subst is a subst…
vjc1234 Mar 18, 2026
c2a111c
integrate structology marshaller
tzhao-viant Mar 18, 2026
4fe7588
Merge branch 'master' into change_to_structology_marshaller
terryzhaobj Mar 18, 2026
b165461
fixed view/codec.go issues
vjc1234 Mar 22, 2026
5d02246
Merge pull request #72 from viant/vc-test
vc42 Mar 23, 2026
11a9fac
Merge branch 'master' into change_to_structology_marshaller
tzhao-viant Mar 23, 2026
f2906f4
Merge pull request #71 from viant/change_to_structology_marshaller
terryzhaobj Mar 23, 2026
b32be4e
init
tzhao-viant Mar 24, 2026
6b03c64
Merge pull request #73 from viant/integrate_structology_jsontab_marshal
adranwit Mar 24, 2026
b643bae
update structology dependency
tzhao-viant Mar 24, 2026
bb646cd
Merge pull request #74 from viant/integrate_structology_jsontab_marshal
terryzhaobj Mar 24, 2026
0efe675
- reporting enhancement
adranwit Mar 25, 2026
0506aa4
- reporting enhancement
adranwit Mar 25, 2026
0b6e9f0
- column discovery enhancement
adranwit Mar 26, 2026
a4dd32d
ENG-00000 adding new finalize-with-error
Mar 26, 2026
28512d5
fixed sequencer issue
tzhao-viant Mar 26, 2026
aaf1cf3
Merge pull request #76 from viant/fixed_sequencer_issue
terryzhaobj Mar 26, 2026
f41687b
remove unecessary init
tzhao-viant Mar 26, 2026
f1261b1
Merge pull request #75 from viant/ENG-00000-feature-request-finalize-…
adranwit Mar 26, 2026
df5d890
- added composite key support
adranwit Mar 31, 2026
be22e55
- added composite key support
adranwit Mar 31, 2026
e50e922
- added composite key support
adranwit Mar 31, 2026
0648d91
- added composite key support
adranwit Mar 31, 2026
14192a6
- added composite key support
adranwit Mar 31, 2026
6df954e
Merge pull request #77 from viant/omposite-key-stable
adranwit Mar 31, 2026
5e41c4e
- fixed multi preficate builders
adranwit Apr 2, 2026
219b01b
- fixed multi preficate builders
adranwit Apr 7, 2026
84b76c7
- updated pointer handling
adranwit Apr 7, 2026
beecea7
- updated pointer handling
adranwit Apr 7, 2026
1127132
ENG-54618 Fix concurrent map write bug in `seedFormFromMultipart` and…
and-bezzir Apr 8, 2026
82c50a7
ENG-54255: enable call to finalize for patch apis even during errors
himanshu808 Apr 8, 2026
9458e61
Merge pull request #79 from viant/ENG-54618-postal-code-issue-with-co…
adranwit Apr 8, 2026
d1c0507
Merge pull request #78 from viant/ENG-54255-finalize-w-errs
adranwit Apr 8, 2026
748d442
- fixed multi preficate builders
adranwit Apr 8, 2026
cd0fe18
- fixed multi predicaet builders/velthy pointer issue
adranwit Apr 8, 2026
f1fb176
- fix predicate extractor
adranwit Apr 8, 2026
99a9ba5
- fix predicate extractor
adranwit Apr 9, 2026
8cacd88
- fix predicate extractor
adranwit Apr 9, 2026
e40dcc4
- fix predicate extractor
adranwit Apr 9, 2026
4da7479
- fix predicate extractor
adranwit Apr 10, 2026
0b34ec9
- patched mcp mapping
adranwit Apr 11, 2026
0b6ae50
fix(session): handle float selector values for limit page and offset
pol-mfilipowicz-viant Apr 22, 2026
6a1892c
concurrent map fix in seedFormFromMultipart
vjc1234 Apr 22, 2026
06c97eb
updated versjion
pol-mfilipowicz-viant Apr 22, 2026
704013d
concurrent map fix in seedFormFromMultipart 2
vjc1234 Apr 22, 2026
c3ef5e3
- patched mcp mapping
adranwit Apr 22, 2026
e1883b2
- patched mcp mapping
adranwit Apr 22, 2026
ab29a24
- patched mcp mapping
adranwit Apr 23, 2026
f9df71f
Restore sanitized translator templates for SQL fragment params
pol-mfilipowicz-viant Apr 23, 2026
72d783f
mutex corruption fix
vjc1234 Apr 23, 2026
a22c829
Merge branch 'master' into vc42_cm
vjc1234 Apr 23, 2026
c8580e7
Merge pull request #83 from viant/vc42_cm
vc42 Apr 23, 2026
080a6fb
- added orig query parameters to cube request
adranwit Apr 29, 2026
4f18a99
Merge remote-tracking branch 'origin/master'
adranwit Apr 29, 2026
c5ebca7
- added orig query parameters to cube request
adranwit Apr 29, 2026
ae441ab
- added orig query parameters to cube request
adranwit Apr 30, 2026
9601df7
- added orig query parameters to cube request
adranwit May 1, 2026
e5b06a3
- added orig query parameters to cube request
adranwit May 1, 2026
161179a
- added orig query parameters to cube request
adranwit May 1, 2026
cc8d9a5
- added orig query parameters to cube request
adranwit May 1, 2026
61b9acb
- added orig query parameters to cube request
adranwit May 3, 2026
709a0df
- added orig query parameters to cube request
adranwit May 4, 2026
f3de5b5
- added orig query parameters to cube request
adranwit May 8, 2026
81706c4
- patched cube
adranwit May 11, 2026
b6bcfaa
- patched duration predicate
adranwit May 11, 2026
7780b95
- extended cache warmup
adranwit May 15, 2026
cb9270a
support xlsx from input
tzhao-viant May 22, 2026
6cf35ef
Merge pull request #84 from viant/support_xlsx
adranwit May 22, 2026
214f285
nested json body marshall/unmarshall in mcp support.
ppoudyal-viant May 27, 2026
a1caf9d
- extended mcp integration
adranwit Jun 12, 2026
69971e1
Merge remote-tracking branch 'origin/master'
adranwit Jun 12, 2026
049c3e4
- extended mcp integration
adranwit Jun 12, 2026
f4a9219
- improved cache warmup
adranwit Jun 12, 2026
07cbe78
Fix JWT RSA auth resource parsing
vc42 Jun 30, 2026
51a54f0
Merge pull request #87 from viant/vc_jwt
vc42 Jun 30, 2026
e0ff74b
Improve cache warmup token and limit handling
vcarey-viant Jul 2, 2026
22f53c8
Merge pull request #88 from viant/vc_warmup
vc42 Jul 2, 2026
98ec04e
Improve warmup metrics and case limits
vcarey-viant Jul 8, 2026
c51b428
Merge pull request #89 from viant/vc_warmup
vc42 Jul 8, 2026
4f24a32
Expose metrics and add request trace correlation
vcarey-viant Jul 9, 2026
129e1c7
Merge pull request #90 from viant/vc_warmup
vc42 Jul 9, 2026
d7fdb8b
Bump sqlx for cache logging updates
vcarey-viant Jul 10, 2026
9414951
Merge pull request #91 from viant/vc_warmup
vc42 Jul 10, 2026
4663163
Fix relation warmup cache identity
vcarey-viant Jul 12, 2026
577230d
Add cache inheritance regression tests
vcarey-viant Jul 12, 2026
7bcd80b
Merge pull request #93 from viant/vc_warmup
vc42 Jul 12, 2026
b9ea741
Fix top-level warmup parameter matching
vcarey-viant Jul 12, 2026
95c3a91
Merge pull request #94 from viant/vc_warmup
vc42 Jul 12, 2026
c7499ac
- added 404 a default response for root or unconfigred paths
adranwit Jul 13, 2026
c01460e
move warmup identity to matcher
vcarey-viant Jul 15, 2026
126f846
Merge branch 'master' into vc_warmup
vcarey-viant Jul 15, 2026
2664a1c
Merge pull request #95 from viant/vc_warmup
vc42 Jul 15, 2026
84614e8
ENG-00001: adding openAPI + swagger
Jul 21, 2026
93430fb
ENG-00001: adding jwt authorize
Jul 21, 2026
ca3534c
ENG-00001: adding jwt authorize 3
Jul 21, 2026
80a5073
- refactored global transaction handling
adranwit Jul 21, 2026
18de046
- refactored global transaction handling
adranwit Jul 22, 2026
35defc3
Merge pull request #96 from viant/ENG-00001-openAPI-Swagger-for-datly
adranwit Jul 22, 2026
b8408a9
TX-00001: error handling changes
Jul 22, 2026
250a1db
Merge pull request #97 from viant/tx
adranwit Jul 23, 2026
74098bf
Update sqlx dependency
vcarey-viant Jul 23, 2026
da75de3
Merge pull request #98 from viant/vc_warmup
vc42 Jul 23, 2026
ff9ed95
Add internal output projection support
vcarey-viant Jul 27, 2026
1257d1b
bypass internal true for warmup
vcarey-viant Jul 27, 2026
4ca1951
Merge pull request #99 from viant/terry_branch
terryzhaobj Jul 27, 2026
c907d72
Improve warmup projection reuse
vcarey-viant Jul 29, 2026
6c2dbbc
Merge pull request #100 from viant/vc_warmup
vc42 Jul 29, 2026
1ebc636
Improve SQL error logging context
vcarey-viant Aug 2, 2026
85ddf61
Merge pull request #101 from viant/vc_sql_error_logging
vc42 Aug 2, 2026
b3788d3
Upgrade viant bigquery dependency
vcarey-viant Aug 3, 2026
43fbe3c
Upgrade sqlx dependency
vcarey-viant Aug 3, 2026
8e45a0f
Merge pull request #102 from viant/vc_bigquery_2873b21
vc42 Aug 3, 2026
3bbe151
ENG-00000: Make generated code and paths.yaml deterministic
and-bezzir Aug 3, 2026
80f5141
Merge pull request #103 from viant/ENG-00000-do-not-change-unrelated-…
adranwit Aug 5, 2026
2b49604
ENG-00000 fix data race on Statelet.Filters
vagarwal-viant Aug 7, 2026
b9c5d49
ENG-00000 fix npe on readRequestBody(nil)
vagarwal-viant Aug 7, 2026
6d09eb7
Merge pull request #104 from vagarwal-viant/master
terryzhaobj Aug 7, 2026
2ef031b
Expose authoritative warmup keys
vcarey-viant Aug 7, 2026
5039b73
Merge remote-tracking branch 'origin/master' into warmup-key-reporting
vcarey-viant Aug 7, 2026
137f78a
Merge pull request #105 from viant/warmup-key-reporting
vc42 Aug 7, 2026
54ae48e
- extended mcp integration
adranwit Aug 10, 2026
14ce561
- extended mcp integration
adranwit Aug 19, 2026
45cce7a
- extended mcp integration
adranwit Aug 20, 2026
862d437
updated sqlx dependency
pol-mfilipowicz-viant Aug 25, 2026
84479cd
updated sqlx dependency v0.25.0
pol-mfilipowicz-viant Aug 26, 2026
5bd890b
- extended mcp integration
adranwit Sep 2, 2026
131f26c
- extended mcp integration
adranwit Sep 3, 2026
cfe8179
- extended mcp integration
adranwit Sep 3, 2026
e9d49c9
- extended mcp integration
adranwit Sep 3, 2026
eee0396
- extended mcp integration
adranwit Sep 3, 2026
4488487
- extended mcp integration
adranwit Sep 4, 2026
6b1df80
- extended mcp integration
adranwit Sep 4, 2026
9ec05a0
- extended mcp integration
adranwit Sep 4, 2026
44f9be5
Expose WithURI routes as distinct MCP tools
adranwit Sep 5, 2026
cfe598a
Preserve explicit MCP tool disablement
adranwit Sep 5, 2026
7503bcb
Preserve explicit MCP tool disablement
adranwit Sep 5, 2026
2bbe358
Merge remote-tracking branch 'origin/master'
adranwit Sep 5, 2026
7221425
- extended mcp integration
adranwit Sep 5, 2026
d8c655f
- extended mcp integration
adranwit Sep 5, 2026
f72de84
Support multipart blobs in MCP tools
adranwit Sep 5, 2026
e9a618f
Support multipart blobs in MCP tools
adranwit Sep 5, 2026
0f158c9
Merge remote-tracking branch 'origin/master'
adranwit Sep 5, 2026
686c0f5
Delegate cube queries with typed selectors
adranwit Sep 5, 2026
db944ce
Inherit MCP exposure for generated cube routes
adranwit Sep 5, 2026
29ad752
Hide internal component inputs from cube contracts
adranwit Sep 5, 2026
e0f6c6f
Bind cube filters to destination form inputs
adranwit Sep 5, 2026
5a56f57
Preserve form filters across cube delegation
adranwit Sep 5, 2026
274a74e
Bind cube destination output through pointer state
adranwit Sep 5, 2026
85e0720
feat(cube): add guarded cube composition
adranwit Sep 6, 2026
5543e5b
Merge remote-tracking branch 'origin/master'
adranwit Sep 6, 2026
faa7e6d
feat(cube): generalize guarded cube composition
adranwit Sep 6, 2026
0d4760e
Merge remote-tracking branch 'origin/master'
adranwit Sep 6, 2026
e741b81
- extended mcp integration
adranwit Sep 6, 2026
4d3e2e3
fix mcp alternate routes and custom bodies
adranwit Sep 8, 2026
13818b9
- extended mcp integration
adranwit Sep 8, 2026
0b30fe3
- extended mcp integration
adranwit Sep 8, 2026
0fdfe53
fix MCP initializer logger context
adranwit Sep 8, 2026
7a6ab03
preserve MCP input presence markers
adranwit Sep 8, 2026
b445e4c
- extended mcp integration
adranwit Sep 8, 2026
957f88a
fix form locator initialization
adranwit Sep 9, 2026
c7297d2
- extended mcp integration
adranwit Sep 9, 2026
b681ee2
test MCP Datly error envelopes
adranwit Sep 9, 2026
e56a7f9
preserve query selectors across handler redirects
adranwit Sep 9, 2026
c5bbac6
Forward query selectors during redirect
vcarey-viant Sep 9, 2026
500a07f
Merge pull request #109 from viant/vc42-redirect
vc42 Sep 9, 2026
bd33e37
Lock shared maps that raced under concurrent reads.
alexis779 Sep 9, 2026
d104f61
Clone selector slices under lock during summary copy.
alexis779 Sep 10, 2026
ec56fb2
Copy collector parent-index positions under lock.
alexis779 Sep 10, 2026
cd2f306
Merge pull request #108 from alexis779/reproduce-column-names-map-race
vc42 Sep 10, 2026
130594a
register local handler parameter types during generation
Sep 12, 2026
c86f814
isolate unavailable MCP integrations
adranwit Sep 15, 2026
cf4f65a
Merge remote-tracking branch 'origin/master'
adranwit Sep 15, 2026
10365a7
accept zero as the first selector page
adranwit Sep 15, 2026
29d96ad
feat: expose cache warmup context to predicates
adranwit Sep 21, 2026
db61171
extend Datly warmup caching
adranwit Sep 21, 2026
294073b
Merge remote-tracking branch 'origin/master'
adranwit Sep 21, 2026
99037d8
fix generated component cache warmups
adranwit Sep 21, 2026
46ee596
ENG-54517 preserve explicit view connectors
adranwit Sep 21, 2026
8b18313
Add scoped cache invalidation and enforce cache expiry configuration
adranwit Sep 22, 2026
c6210cd
Verify live Aerospike lazy and warmup expiry with bounded polling
adranwit Sep 22, 2026
752ab5d
Expose cache creation metrics and timestamps with latest SQLX
adranwit Sep 22, 2026
7219384
Merge remote-tracking branch 'origin/master'
adranwit Sep 22, 2026
436669a
ENG-54517 match authorized performance scopes to warmup indexes
adranwit Sep 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gcloudignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ e2e/
.gitignore
*.yaml
*.md
secrets.json
secrets.json
.meta
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@
secrets.json
*.db
local_test.go
vendor
vendor/
datly
other
mydb
tmp/
*.gz
.DS_Store
autogen
dql
dql
*.iml
*.so
logs
.extension
.datly
*.zip
local
v1/
2 changes: 1 addition & 1 deletion Version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.20.2
v0.38.0
152 changes: 152 additions & 0 deletions cache-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Cache management

Datly uses SQLX main revision `031ed89ced07` and xdatly/handler revision
`34eaa9f4902b`, and adds persistent, view-scoped generations to native
cache identities. Both request-populated (lazy) and prewarmed entries remain
subject to their configured TTL.

## Invalidate a component or view

For a GET component at `/v1/api/orders`, Datly registers:

```http
POST /v1/api/cache/invalidate/orders
Content-Type: application/json

{"scope":"all"}
```

The path follows the same component-prefix mapping as the existing warmup route.
`Meta.CacheInvalidateURI` configures the prefix, defaulting to
`/v1/api/cache/invalidate`.

- `all` (default) retires lazy entries and warmup publications.
- `lazy` retires request-populated entries only. Warmup hits remain eligible.
- `warmup` retires prewarmed entries only. Existing lazy hits remain eligible.
- `view` optionally selects a view by name, including a nested view. Omitting it
selects every cached view reachable through the component's `With` relations,
including views without a warmup configuration.

```json
{"view":"order_items","scope":"lazy"}
```

An empty request body defaults to `all`. The response reports each view's scope
and new generation. Unknown views return 404; invalid JSON, unknown properties,
and invalid scopes return 400. Storage failures return 500 with per-view results;
a multi-view request is not a transaction, so some views can succeed while others
fail. Retrying invalidation is safe.

The route inherits the component's API-key requirements and the gateway's subnet
policy. Invalidating caches requires the same deployment access controls as other
administrative routes. Rejected API keys stop execution before any mutation.

## Repopulate after invalidation

Invalidation does not query the database. The next request fills a lazy entry.
To repopulate configured warmups, call the existing route after invalidation:

```http
POST /v1/api/cache/warmup/orders
```

Use `all` before warming if previously populated lazy results must also be
retired. `warmup` alone intentionally preserves lazy results. Invalidating a
warmup retires every configured warmup case for the selected view.

A forced reader cache refresh retires both generations for the view before
reading. This is intentionally broader than an exact-query refresh, and prevents
Aerospike from satisfying the refresh with an older warmup publication.

## Storage and concurrency

A cache owner is derived from the resource identity, view name, and connector
configuration. Resource paths below `/routes/` are made route-relative so replicas
with different deployment roots agree. Views with the same owner intentionally
share their cache; invalidation affects that shared view wherever it is used.
Standalone resources outside `/routes/` need consistent resource URLs across
replicas. Read SQL is unchanged. Warmup queries receive a cache-identity SQL
comment; query semantics and bound arguments are unchanged.

AFS stores generation files under `<expanded location>/.datly-generations/<owner>`.
Local generation changes use atomic file replacement. Object-storage deployments
must provide atomic object replacement and read-after-write consistency for these
control objects. Aerospike stores a permanent control record per owner, with
independent `all`, `lazy`, and `warmup` bins. Concurrent scope changes do not
replace one another's bins.

Readers obtain the shared generation on every lookup. Operations already in
flight may finish using their captured generation. A writer that started before
invalidation can only publish into its old generation; later lookups cannot use
it. All cache instances must use the same underlying storage to share invalidation;
separate local disks and per-process memory caches are independently managed.

Generation controls must be retained and excluded from external cache cleanup or
Aerospike eviction. Removing control state while retaining payloads can make old
generations reachable. Invalidation is logical, not a storage purge. Aerospike
reclaims old payloads through its TTL. AFS does not run a background garbage
collector: retain your storage lifecycle/cleanup policy for expired JSON payloads,
excluding `.datly-generations`.

Upgrading introduces a new cache-key namespace, so existing cache entries are
cold until lazily refilled or prewarmed. Existing payloads need normal cleanup.

## TTL and location configuration

`TimeToLiveMs` must be positive and fit in a Go duration. For Aerospike, it must
be an exact number of seconds; subsecond/fractional-second values and reserved
server TTL values are rejected instead of truncated. For example, use `1000` or
`60000`, not `500` or `1500`. AFS supports millisecond TTLs.

Cache-provider locations support view expansion:

```yaml
CacheProviders:
- Name: local
Location: /cache/${View.Name}
TimeToLiveMs: 60000
```

`${View.Alias}` and `${View.Table}` are also supported. The escaped-dot forms
(`${View\.Name}`, `${View\.Alias}`, `${View\.Table}`) are accepted too. For Aerospike the expanded
location is the set name and must satisfy Aerospike's set-name rules.

## Verification

The managed-cache tests exercise native AFS/SQLite cache reads and writes, TTL
expiry, both warmup forms, scope isolation, owner isolation, refresh, persistence
across cache instances, and invalidation during lazy/warmup writes. HTTP tests
cover nested lazy-only views, input errors, and API-key rejection. Generation-store
tests cover concurrent file publication and Aerospike's independent bins and
nonexpiring control-record write policy.

A live Aerospike test is available against a dedicated test server:

```sh
DATLY_TEST_AEROSPIKE=aerospike://127.0.0.1:3000/test \
go test ./internal/cache/managed -run TestManagedAerospikeIntegration -count=1 -v
```

The existing `e2e/local/system.yaml` uses Aerospike `ce-6.2.0.2` at that address.
The test uses unique owner identities in `datly_cache_test`, short payload TTLs,
and removes its own generation records. It does not truncate a namespace or set.
It is skipped when `DATLY_TEST_AEROSPIKE` is unset.

## Creation metrics

Per-view counters expose `cache:created`, `cache:lazy_created`, and
`cache:warmup_created`. These count successfully published cache entries, not
lookup misses or write attempts. Index markers count as entries; overflow chunks
do not. Hits, reused AFS warmups, failed writes, and rolled-back requests do not
increment creation counters. Empty results count when their cache entry or index
marker is published. `cache:miss_write` remains the separate write-attempt counter.

SQLX caches with `SetCreationObserver(func(kind string, entries int))` report
both lazy and warmup publications. Cache implementations without the observer use Datly's successful
lazy-close fallback; exact warmup creation counts require the native observer.
Existing warmup run/group metrics remain available independently.

With the updated shared response contract, SQL execution metrics expose
`cacheStats.createdTime` alongside `expiryTime`. Creation time is persisted by
SQLX and stays unchanged on cache hits. Legacy entries without a stored creation
time omit the field. Datly copies the timestamp after cache publication completes.
2 changes: 1 addition & 1 deletion cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package cmd
import (
"context"
"fmt"

"github.com/jessevdk/go-flags"
"github.com/viant/datly/cmd/command"
soptions "github.com/viant/datly/cmd/options"
)

func RunApp(version string, args soptions.Arguments) error {

options, err := buildOptions(args)
if err != nil {
return err
Expand Down
33 changes: 33 additions & 0 deletions cmd/command/async_defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package command

import (
"github.com/viant/afs/file"
"github.com/viant/afs/url"
"github.com/viant/datly/gateway/runtime/standalone"
)

const (
defaultJobURL = "/tmp/datly/jobs"
defaultFailedJobURL = "/tmp/datly/failed"
)

func applyAsyncJobDefaults(config *standalone.Config) {
if config == nil {
return
}

if config.JobURL == "" && config.FailedJobURL == "" {
config.JobURL = defaultJobURL
config.FailedJobURL = defaultFailedJobURL
return
}

if config.JobURL == "" {
config.JobURL = defaultJobURL
}

if config.FailedJobURL == "" {
parent, _ := url.Split(config.JobURL, file.Scheme)
config.FailedJobURL = url.Join(parent, "failed", "jobs")
}
}
51 changes: 51 additions & 0 deletions cmd/command/async_defaults_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package command

import (
"testing"

"github.com/viant/datly/gateway"
"github.com/viant/datly/gateway/runtime/standalone"
)

func TestApplyAsyncJobDefaults(t *testing.T) {
testCases := []struct {
name string
jobURL string
failedJobURL string
expectJob string
expectFailed string
}{
{
name: "both empty use tmp defaults",
expectJob: "/tmp/datly/jobs",
expectFailed: "/tmp/datly/failed",
},
{
name: "custom job only derives failed path",
jobURL: "/custom/jobs",
expectJob: "/custom/jobs",
expectFailed: "file://localhost/custom/failed/jobs",
},
{
name: "failed only keeps failed and defaults job",
failedJobURL: "/custom/failed",
expectJob: "/tmp/datly/jobs",
expectFailed: "/custom/failed",
},
}

for _, testCase := range testCases {
cfg := &standalone.Config{Config: &gateway.Config{}}
cfg.JobURL = testCase.jobURL
cfg.FailedJobURL = testCase.failedJobURL

applyAsyncJobDefaults(cfg)

if cfg.JobURL != testCase.expectJob {
t.Fatalf("%s: expected JobURL=%s, got %s", testCase.name, testCase.expectJob, cfg.JobURL)
}
if cfg.FailedJobURL != testCase.expectFailed {
t.Fatalf("%s: expected FailedJobURL=%s, got %s", testCase.name, testCase.expectFailed, cfg.FailedJobURL)
}
}
}
Loading
Loading