You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/docs/advanced_topics/memoization_keys.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ The following types are handled automatically (no custom key needed):
29
29
30
30
The key fragments are combined into a deterministic fingerprint. If the fingerprint matches a cached entry, the cached result is reused — unless **memo states** indicate it's stale (see [Memo state validation](#memo-state-validation) below).
31
31
32
-
In addition to input fingerprints, CocoIndex also validates against **function code fingerprints** and **[tracked context value](../programming_guide/context.md#tracked-context-keys) fingerprints**. If the function's code or any tracked context value it consumed has changed, the cached result is invalidated regardless of input matching.
32
+
In addition to input fingerprints, CocoIndex also validates against **function code fingerprints** and **[tracked context value](../programming_guide/context.md#tracked-context-keys) fingerprints**. If the function's code or any tracked context value it consumed has changed, the cached result is invalidated regardless of input matching. You can control the scope of code change tracking with the [`logic_tracking` parameter](../programming_guide/function.md#logic_tracking).
Copy file name to clipboardExpand all lines: docs/docs/programming_guide/function.md
+54-5Lines changed: 54 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,19 +64,68 @@ See [Memoization Keys & States](../advanced_topics/memoization_keys.md) for deta
64
64
65
65
### Change tracking
66
66
67
-
The logic of a function decorated with `@coco.fn`is tracked based on the content of the function. When a function's implementation changes, CocoIndex detects this and re-executes the places where it's called.
67
+
Every `@coco.fn`function has its code fingerprinted. These fingerprints propagate up the call chain: when a function's code changes, all memoized callers and components that transitively depend on it are invalidated. Two parameters let you customize this:
68
68
69
-
In addition to code changes, [tracked context values](./context.md#tracked-context-keys) consumed via `coco.use_context()` are also tracked. When a tracked context value changes between runs, functions that used it are re-executed — even if the function code and inputs are unchanged.
69
+
-**`logic_tracking`** — controls the *scope* of automatic code change tracking
70
+
-**`version`** — provides explicit manual control over when dependent memos are invalidated
70
71
71
-
You can also explicitly control the behavior version with a `version` option:
72
+
#### `logic_tracking`
73
+
74
+
The `logic_tracking` parameter controls whether and how function code changes are detected:
75
+
76
+
-**`"full"` (default):** Track this function's code AND all transitively called `@coco.fn` functions' code. A change anywhere in the call chain invalidates dependent memos.
77
+
-**`"self"`:** Track only this function's own code. Changes in called functions do not propagate through this function.
78
+
-**`None`:** Don't track this function's code at all. Code changes to this function are invisible to the change tracking system.
79
+
80
+
#### `version`
81
+
82
+
The `version` parameter lets you explicitly invalidate dependent memos by bumping an integer:
72
83
73
84
```python
74
-
@coco.fn(memo=True, version=2)
85
+
@coco.fn(version=2)
75
86
defprocess_chunk(chunk: Chunk) -> Embedding:
76
-
# Bumping version forces re-execution even if code looks the same
87
+
# Bumping version invalidates all memoized callers, even if code looks the same
77
88
return embed(chunk.text)
78
89
```
79
90
91
+
#### Common patterns
92
+
93
+
These parameters can be set on any `@coco.fn` function — not just memoized ones. A non-memoized function's fingerprint still propagates to its memoized callers and components.
94
+
95
+
**Fully automatic (default)** — use `logic_tracking="full"` (or omit it) without setting `version`. Any code change in the function or its callees invalidates dependent memos. This always just works.
# Any change here or in called @coco.fn functions invalidates dependent memos
101
+
text =awaitfile.read_text()
102
+
return split_and_embed(text)
103
+
```
104
+
105
+
**Manual, precise control** — use `logic_tracking="self"` with `version`. You decide what counts as a behavior change by bumping `version`, without being affected by implementation detail changes (performance optimizations, logging tweaks, refactoring, etc.).
106
+
107
+
```python
108
+
@coco.fn(logic_tracking="self", version=3)
109
+
asyncdefprocess(data: str) -> str:
110
+
# Bump version when behavior changes (e.g., new output format).
111
+
# Internal refactors or logging changes won't trigger reprocessing.
112
+
returnawait transform(data)
113
+
```
114
+
115
+
**Opt out of tracking** — use `logic_tracking=None` for functions with a stable contract (where code changes don't affect output), or functions whose changes don't affect behavior (e.g., logging, performance hints). This prevents unnecessary reprocessing when only internals change.
116
+
117
+
```python
118
+
@coco.fn(logic_tracking=None)
119
+
defembed(text: str) -> list[float]:
120
+
# Contract is stable: same input always produces the same embedding.
121
+
# Internal changes (e.g., switching backends) are handled by version bumps.
122
+
return model.encode(text)
123
+
```
124
+
125
+
:::note
126
+
[Tracked context values](./context.md#tracked-context-keys) consumed via `coco.use_context()` are always tracked regardless of the `logic_tracking` setting. Even with `logic_tracking=None`, a change in a tracked context value still invalidates dependent memos.
127
+
:::
128
+
80
129
### Async adapter
81
130
82
131
Use `@coco.fn.as_async` when you need an **async** interface for a function that has a sync underlying implementation. This is useful for compute-intensive leaf functions, and is required for features like [batching](#batching) and [runner](#runner).
0 commit comments