Skip to content

Commit 1fdf915

Browse files
committed
fix(ui): distinguish strict and explicit cache-release counts
1 parent 49dbe08 commit 1fdf915

8 files changed

Lines changed: 55 additions & 15 deletions

File tree

docs/en/concepts/filecoin-storage-flow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ If an established provider becomes temporarily unavailable while the initial cop
5656

5757
## Target and Minimum Replicas
5858

59-
The target replica count is frozen when an upload starts. By default, Release cache after is All replicas (strict): every target replica frozen for that upload must be readable and committed. A bucket can instead set an explicit count from 1 through the current target. An explicit count stays fixed if the target later changes; All replicas follows each upload's frozen target. Once that threshold is met, the version becomes stored and its cache follows the configured eviction policy, while the upload continues filling its original replica slots until the target is reached. The dashboard keeps showing replica sync progress until every frozen target replica is done.
59+
The target replica count is frozen when an upload starts. By default, **Release cache after** is **All replicas (strict)**: every target replica frozen for that upload must be readable and committed. A bucket can instead set an explicit count from 1 through the current target. An explicit count stays if Replicas later increases; lowering Replicas below that count is rejected until Release cache after is also lowered. **All replicas (strict)** follows each upload's frozen target. Once that threshold is met, the version becomes stored and its cache follows the configured eviction policy, while remaining replicas continue until the upload's target is reached. The dashboard keeps showing replica sync progress until every frozen target replica is done.
6060

6161
Changing the target affects new uploads. Changing the minimum also re-evaluates retained cache for current uploads. Increasing the minimum does not move versions that are already stored back to an earlier state and cannot restore cache that has already been deleted.
6262

docs/en/concepts/write-path-cache.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Repeated reads of the same version coalesce access-time updates to at most one d
4242
| `after_upload` | Queue each version for removal after its bucket's minimum durable copies commit. |
4343
| `none` | Do not create or run automatic cache eviction work. |
4444

45-
Each bucket defaults to strict cache release, so the minimum equals the target replicas frozen for each upload. An operator can set an explicit count from 1 through the current target; that number stays fixed if the target later changes. Lowering the threshold makes retained cache eligible for removal while original replica slots continue syncing. Actual removal still follows `after_upload`, `lru`, or `none`. The minimum is clamped to each upload's target. Raising it affects cache that still exists; it cannot recreate cache that has already been deleted.
45+
Each bucket defaults to strict cache release, so the minimum equals the target replicas frozen for each upload. In the dashboard, set this on the bucket under Settings → Replica policy. An operator can set an explicit count from 1 through the current target. That count stays if Replicas later increases. Lowering Replicas below the stored count is rejected until Release cache after is also lowered. Lowering the threshold makes retained cache eligible for removal while remaining replicas continue syncing. Actual removal still follows `after_upload`, `lru`, or `none`. The minimum is clamped to each upload's target. Raising it affects cache that still exists; it cannot recreate cache that has already been deleted.
4646

4747
Only versions that currently meet their minimum and have a readable committed remote copy are eligible. Eviction checks the current minimum again before authorizing deletion and waits for active reads of the same version to close. Because cleanup is asynchronous, writes can still return `507 Insufficient Storage` when cleanup cannot keep pace or no safe candidate exists.
4848

docs/zh/concepts/filecoin-storage-flow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ synaps3 admin task retry 42
5656

5757
## 目标副本与最低耐久副本
5858

59-
上传开始时会冻结目标副本数。默认情况下,Release cache after 为 All replicas (strict):该次上传冻结的全部目标副本都必须可读并完成提交。存储桶也可以设置 1 到当前目标之间的显式数量。显式数量在目标随后提高时保持不变;All replicas 会跟随每次上传冻结的目标。达到该门槛后,版本进入已存储状态,缓存按已配置的淘汰策略处理;上传仍会继续补齐原有副本位,直到达到目标副本数。在冻结的目标副本全部完成前,仪表盘会继续显示副本同步进度。
59+
上传开始时会冻结目标副本数。默认情况下,**Release cache after****All replicas (strict)**:该次上传冻结的全部目标副本都必须可读并完成提交。存储桶也可以设置 1 到当前目标之间的显式数量。显式数量在目标随后提高时保持不变;如果把 Replicas 降到低于该数量,请求会被拒绝,必须同时降低 Release cache after。**All replicas (strict)** 会跟随每次上传冻结的目标。达到该门槛后,版本进入已存储状态,缓存按已配置的淘汰策略处理;其余副本会继续补齐,直到达到该次上传的目标副本数。在冻结的目标副本全部完成前,仪表盘会继续显示副本同步进度。
6060

6161
修改目标副本数只影响新上传。修改最低耐久副本数也会重新评估当前上传仍保留的缓存。提高门槛不会让已经进入已存储状态的版本回退,也无法恢复已经删除的缓存。
6262

docs/zh/concepts/write-path-cache.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ SynapS3 会校验请求,保存对象及其元数据,再返回 S3 兼容的 E
4242
| `after_upload` | 存储桶要求的最低耐久副本提交后,为该版本排队清理。 |
4343
| `none` | 不创建或执行自动缓存淘汰任务。 |
4444

45-
每个存储桶默认采用严格缓存释放策略,因此最低耐久副本数等于每次上传冻结的目标副本数。运维人员可以设置 1 到当前目标之间的显式数量;目标随后提高时该数字保持不变。降低门槛只会让仍保留的缓存有资格被删除,原副本位会继续补齐。是否真正删除仍取决于 `after_upload``lru``none`。该门槛不会超过单次上传的目标副本数。提高门槛只影响尚未删除的缓存,无法恢复已经删除的缓存。
45+
每个存储桶默认采用严格缓存释放策略,因此最低耐久副本数等于每次上传冻结的目标副本数。在仪表盘中,到该存储桶的 Settings → Replica policy 设置。运维人员可以设置 1 到当前目标之间的显式数量;目标随后提高时该数字保持不变。如果把 Replicas 降到低于已保存的显式数量,请求会被拒绝,必须同时降低 Release cache after。降低门槛只会让仍保留的缓存有资格被删除,其余副本会继续补齐。是否真正删除仍取决于 `after_upload``lru``none`。该门槛不会超过单次上传的目标副本数。提高门槛只影响尚未删除的缓存,无法恢复已经删除的缓存。
4646

4747
只有当前满足最低耐久副本数且存在可读已提交远端副本的版本才可淘汰。系统会在授权删除前再次检查当前门槛,并等待同一版本正在进行的读取关闭。清理是异步流程,因此清理追赶不及时或没有安全候选时,写入仍可能返回 `507 Insufficient Storage`
4848

ui/src/lib/bucket-copy-policy.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,20 @@ export function bucketCopyPolicyInheritOptionLabel(bucket: BucketCopyPolicy, run
2424
return `Inherit current runtime default (${copyCountLabel(copies)})`
2525
}
2626

27+
export function replicaTargetChoiceNote() {
28+
return 'Applies to new uploads. Existing objects keep the replica target they started with.'
29+
}
30+
2731
export function bucketCopyPolicySavedMessage() {
28-
return 'Replica policy saved.'
32+
return 'Saved. New uploads use this replica target. Cache can be released after the selected count.'
2933
}
3034

3135
export function minimumDurableCopiesChoiceNote() {
32-
return 'Waits for every target replica of that upload.'
36+
return 'Keeps cache until every replica of that upload is stored, including later Replicas increases.'
37+
}
38+
39+
export function minimumDurableCopiesFixedCountNote() {
40+
return 'Keeps this count if Replicas later increases.'
3341
}
3442

3543
export function minimumDurableCopiesValue(bucket: Pick<BucketItem, 'minimum_durable_copies' | 'effective_copies'>) {
@@ -43,8 +51,12 @@ export function minimumDurableCopiesLabel(bucket: BucketCopyPolicy) {
4351
return `${bucket.effective_minimum_durable_copies} of ${bucket.effective_copies} ${bucket.effective_copies === 1 ? 'replica' : 'replicas'}`
4452
}
4553

46-
export function minimumDurableCopiesOptionLabel(copies: number) {
47-
return `${copies} ${copies === 1 ? 'replica' : 'replicas'}`
54+
export function minimumDurableCopiesOptionLabel(copies: number, targetCopies?: number | null) {
55+
const count = `${copies} ${copies === 1 ? 'replica' : 'replicas'}`
56+
if (targetCopies != null && copies === targetCopies) {
57+
return `${count} (fixed count)`
58+
}
59+
return count
4860
}
4961

5062
export function selectedTargetCopies(copyPolicy: string, runtimeDefaultCopies?: number) {

ui/src/routes/buckets.$name.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,14 @@ import {
122122
copyPolicyOptions,
123123
inheritedCopyPolicyValue,
124124
minimumDurableCopiesChoiceNote,
125+
minimumDurableCopiesFixedCountNote,
125126
minimumDurableCopiesLabel,
126127
minimumDurableCopiesOptionLabel,
127128
minimumDurableCopiesOptions,
128129
minimumDurableCopiesValue,
129130
minimumDurableCopiesWarning,
130131
persistMinimumDurableCopies,
132+
replicaTargetChoiceNote,
131133
selectedTargetCopies,
132134
showsMinimumDurableCopiesWarning,
133135
strictMinimumDurableCopiesValue,
@@ -2316,6 +2318,7 @@ function BucketDetailsSettings({
23162318
</SelectGroup>
23172319
</SelectContent>
23182320
</Select>
2321+
<FieldDescription>{replicaTargetChoiceNote()}</FieldDescription>
23192322
</Field>
23202323
<Field>
23212324
<FieldLabel htmlFor={`bucket-minimum-durable-copies-${bucket.id}`}>Release cache after</FieldLabel>
@@ -2332,14 +2335,16 @@ function BucketDetailsSettings({
23322335
<SelectItem value={strictMinimumDurableCopiesValue}>All replicas (strict)</SelectItem>
23332336
{minimumOptions.map((copies) => (
23342337
<SelectItem key={copies} value={copies.toString()}>
2335-
{minimumDurableCopiesOptionLabel(copies)}
2338+
{minimumDurableCopiesOptionLabel(copies, targetCopies)}
23362339
</SelectItem>
23372340
))}
23382341
</SelectGroup>
23392342
</SelectContent>
23402343
</Select>
2341-
{minimumDurableCopies === strictMinimumDurableCopiesValue && (
2344+
{minimumDurableCopies === strictMinimumDurableCopiesValue ? (
23422345
<FieldDescription>{minimumDurableCopiesChoiceNote()}</FieldDescription>
2346+
) : (
2347+
<FieldDescription>{minimumDurableCopiesFixedCountNote()}</FieldDescription>
23432348
)}
23442349
</Field>
23452350
</FieldGroup>

ui/src/routes/buckets.index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ import {
3131
copyPolicyOptions,
3232
inheritedCopyPolicyValue,
3333
minimumDurableCopiesChoiceNote,
34+
minimumDurableCopiesFixedCountNote,
3435
minimumDurableCopiesLabel,
3536
minimumDurableCopiesOptionLabel,
3637
minimumDurableCopiesOptions,
3738
minimumDurableCopiesWarning,
39+
replicaTargetChoiceNote,
3840
selectedTargetCopies,
3941
showsMinimumDurableCopiesWarning,
4042
strictMinimumDurableCopiesValue,
@@ -184,11 +186,13 @@ function CreateBucketDialog() {
184186
</SelectGroup>
185187
</SelectContent>
186188
</Select>
187-
{copyPolicy === inheritedCopyPolicyValue && runtimeDefaultCopies == null && (
189+
{copyPolicy === inheritedCopyPolicyValue && runtimeDefaultCopies == null ? (
188190
<FieldDescription>
189191
The current runtime default is unavailable. Choose a replica count to configure an explicit
190192
cache-release threshold.
191193
</FieldDescription>
194+
) : (
195+
<FieldDescription>{replicaTargetChoiceNote()}</FieldDescription>
192196
)}
193197
</Field>
194198
<Field>
@@ -206,14 +210,16 @@ function CreateBucketDialog() {
206210
<SelectItem value={strictMinimumDurableCopiesValue}>All replicas (strict)</SelectItem>
207211
{minimumOptions.map((copies) => (
208212
<SelectItem key={copies} value={copies.toString()}>
209-
{minimumDurableCopiesOptionLabel(copies)}
213+
{minimumDurableCopiesOptionLabel(copies, targetCopies)}
210214
</SelectItem>
211215
))}
212216
</SelectGroup>
213217
</SelectContent>
214218
</Select>
215-
{minimumDurableCopies === strictMinimumDurableCopiesValue && (
219+
{minimumDurableCopies === strictMinimumDurableCopiesValue ? (
216220
<FieldDescription>{minimumDurableCopiesChoiceNote()}</FieldDescription>
221+
) : (
222+
<FieldDescription>{minimumDurableCopiesFixedCountNote()}</FieldDescription>
217223
)}
218224
</Field>
219225
</FieldGroup>

ui/test/bucket-copy-policy.test.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,36 @@ import {
66
bucketCopyPolicySavedMessage,
77
clampMinimumDurableCopiesValue,
88
minimumDurableCopiesChoiceNote,
9+
minimumDurableCopiesFixedCountNote,
910
minimumDurableCopiesLabel,
11+
minimumDurableCopiesOptionLabel,
1012
minimumDurableCopiesOptions,
1113
minimumDurableCopiesValue,
1214
minimumDurableCopiesWarning,
1315
persistMinimumDurableCopies,
16+
replicaTargetChoiceNote,
1417
selectedTargetCopies,
1518
showsMinimumDurableCopiesWarning,
1619
strictMinimumDurableCopiesValue,
1720
} from '../src/lib/bucket-copy-policy.ts'
1821

1922
test('bucket copy policy text explains save result and future upload scope', () => {
20-
assert.equal(bucketCopyPolicySavedMessage(), 'Replica policy saved.')
21-
assert.equal(minimumDurableCopiesChoiceNote(), 'Waits for every target replica of that upload.')
23+
assert.equal(
24+
replicaTargetChoiceNote(),
25+
'Applies to new uploads. Existing objects keep the replica target they started with.'
26+
)
27+
assert.equal(
28+
bucketCopyPolicySavedMessage(),
29+
'Saved. New uploads use this replica target. Cache can be released after the selected count.'
30+
)
31+
assert.equal(
32+
minimumDurableCopiesChoiceNote(),
33+
'Keeps cache until every replica of that upload is stored, including later Replicas increases.'
34+
)
35+
assert.equal(minimumDurableCopiesFixedCountNote(), 'Keeps this count if Replicas later increases.')
36+
assert.equal(minimumDurableCopiesOptionLabel(3), '3 replicas')
37+
assert.equal(minimumDurableCopiesOptionLabel(3, 3), '3 replicas (fixed count)')
38+
assert.equal(minimumDurableCopiesOptionLabel(2, 3), '2 replicas')
2239
assert.equal(
2340
minimumDurableCopiesWarning(),
2441
'Cache may be removed before every target replica is ready. Raising this later cannot restore deleted cache.'

0 commit comments

Comments
 (0)