zeng-bohan
ce3e64242b
feat(gateway): checkpoint retention service on the #4189 deletion contract ( #5308 )
...
* feat(gateway): thread checkpoint retention service on the #4189 deletion contract
Implements exactly the two contract-proven deletion shapes (trailing
duration-only leaves, opt-in leaf sibling branches) with head-chain
protection, explicit id protection, a strict pending-writes guard, and
joint writes-row cleanup. Head resolution uses LangGraph's time-ordered
checkpoint ids; storage deletion mirrors the contract's per-backend data
model. Ships without a production trigger by design. Validated against
the contract suite (12 passed) plus 14 service scenarios across memory
and SQLite; Postgres paths are gated on TEST_POSTGRES_URI.
Signed-off-by: zengbohan1 <310902929+zengbohan1@users.noreply.github.com>
* fix(gateway): survivor-reachability blob GC and memory blob stats in retention service
Aligns the deletion service with the review-hardened contract: blob rows
are garbage-collected in a whole-thread pass against surviving
checkpoints' channel_versions (a real duration-only leaf shares its
parent's versions, so per-checkpoint version deletion would corrupt the
surviving state), the memory branch of the stats helper counts
saver.blobs and returns the full normalized shape, and per-node channel
versions are collected during the graph pass that already exists.
Signed-off-by: zengbohan1 <310902929+zengbohan1@users.noreply.github.com>
* fix(gateway): address review findings on checkpoint retention service
Resolves the review at a479cfe (willem-bd):
- Untested savers now fail fast: an explicit isinstance allowlist
(InMemorySaver / AsyncSqliteSaver / AsyncPostgresSaver) raises
NotImplementedError before any row is read or deleted, so a shallow or
third-party saver can never issue partial DELETEs.
- The chain walk ends (break) instead of raising KeyError when the head's
ancestor row is missing, matching the deletable loop's tolerance for
missing parents.
- enforce_thread_retention takes an optional per-thread lock and documents
the concurrency requirement: classification and deletion are two separate
passes, so callers must serialize per-thread mutation (runtime
_checkpoint_thread_lock) or guarantee quiescence.
- Dropped the dead mid-run guard: CheckpointTuple has no `next` field in
langgraph-checkpoint 4.1.1, and pending_writes is populated for committed
writes too (verified on the list path), so neither is a usable mid-run
signal; the caller-held thread lock is the actual protection.
- Removed the write-only _node_step/_Node.step and fixed the head-selection
docstring (newest by checkpoint id, not (step, checkpoint_id)).
- Documented the E1 leaf / history fast-path interaction in the contract doc
and module docstring: the wiring PR must sequence retention away from
history reads or adopt a policy that spares cache-carrying leaves.
- Added regression tests: unsupported saver, missing ancestor row, thread
lock parameter.
Validation: test_checkpoint_retention_service 18 passed / 8 postgres-gated
skipped; contract + lineage suites 18 passed / 6 skipped; ruff check and
format clean.
* fix(retention): count non-empty writes dicts on memory saver
- _checkpoint_ids_with_writes now requires a non-empty writes dict on
InMemorySaver: the empty phantom entry for checkpoints whose task wrote
nothing no longer counts as "owns writes rows", so the default E1 pruning
reaches the memory backend again (it was a silent no-op there).
- test_runtime_duration_leaf_pruned_by_default runs the shipping default
(strict_pending_write_guard=True) and proves E1 is reachable out of the
box on every backend; the stale override and its wrong SQLite premise
are dropped.
- document that _checkpoint_thread_lock is non-reentrant: a caller already
holding it must not pass it in, or retention self-deadlocks.
* test(checkpoint-retention): fix stray duplicated def token in test_duration_link_protected_after_next_run
The previous push left `async def def test_...` at line 244, which made the
module unimportable and failed collection of the whole suite (and ruff
format --check). Local copy was already correct; this commit re-pushes the
clean file. 18 passed / 8 postgres-skipped verified from a head worktree.
* fix(gateway): make retention correct on Postgres and fail closed on a bad cap
* validate max_delete_per_run before any store read: a negative cap used to
widen the batch (Python slicing) instead of being rejected;
* report identical before/after stats for an empty thread instead of returning
before stats_after is collected;
* protect each namespace's resume head and ancestor chain, so a persistent
subgraph's latest checkpoint is no longer treated as a sibling leaf;
* read Postgres columns through a row-factory-agnostic helper (the PG savers
open cursors with dict_row, where positional access raises KeyError: 0);
* classify the duration-only leaf without relying on metadata["writes"], which
the Postgres saver strips via get_serializable_checkpoint_metadata.
Verified locally on memory, SQLite and a real Postgres 16 instance (62 passed,
0 skipped): the E1 shape now fires on Postgres, which no backend test covered
before CI ran the Postgres lig.
Signed-off-by: zeng-bohan <zengbh1@gmail.com>
* test(gateway): pin the Postgres-shape duration classifier; report per-namespace heads
- Deterministic regression for _mark_duration_leaves_without_the_marker:
hand-put the Postgres round-trip shape (writes marker popped, source=
update + accumulated run_durations + channel_versions identical to the
parent) and assert the shipping default prunes it; a control that bumps
one channel version (the client update_state shape) with otherwise
identical metadata stays protected. Both legs run on memory and SQLite,
so the class cannot silently re-widen (a resumable head losing head
protection) or re-narrow (E1 never firing on Postgres) without a
locally-executing test failing.
- RetentionReport.protected_head_id -> protected_head_ids: heads are now
selected per namespace, so the report carries every namespace's head
(root key = what an unsaved aget_tuple resolves) instead of only the
global max - reshape it before the wiring PR starts consuming reports
for audit/aggregation.
---------
Signed-off-by: zengbohan1 <310902929+zengbohan1@users.noreply.github.com>
Signed-off-by: zeng-bohan <zengbh1@gmail.com>
Co-authored-by: zengbohan1 <310902929+zengbohan1@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-09-18 16:46:19 +08:00
..
2026-09-18 11:32:04 +08:00
2026-09-13 20:28:32 +08:00
2026-07-19 18:26:26 +08:00
2026-09-14 11:01:31 +08:00
2026-05-12 23:18:54 +08:00
2026-09-14 11:10:41 +08:00
2026-07-26 14:43:08 +08:00
2026-04-26 15:09:25 +08:00
2026-06-01 15:50:39 +08:00
2026-09-15 07:26:08 +08:00
2026-09-12 10:59:31 +08:00
2026-09-01 16:49:39 +08:00
2026-07-21 11:46:33 +08:00
2026-06-21 20:56:42 +08:00
2026-06-08 12:35:03 +08:00
2026-09-12 09:28:46 +08:00
2026-07-22 14:47:08 +08:00
2026-08-30 10:30:34 +08:00
2026-07-17 15:11:15 +08:00
2026-09-16 18:46:18 +08:00
2026-09-12 11:09:41 +08:00
2026-09-17 09:13:40 +08:00
2026-09-14 18:17:54 +08:00
2026-09-02 12:34:09 +08:00
2026-09-12 11:09:41 +08:00
2026-08-24 11:04:23 +08:00
2026-09-17 07:55:22 +08:00
2026-09-04 23:46:57 +08:00
2026-09-17 07:45:19 +08:00
2026-09-04 23:46:57 +08:00
2026-09-17 07:45:19 +08:00
2026-06-23 10:39:40 +08:00
2026-09-12 10:57:40 +08:00
2026-09-12 07:12:37 +08:00
2026-09-16 18:46:18 +08:00
2026-09-12 07:41:24 +08:00
2026-05-29 23:05:59 +08:00
2026-09-17 22:13:53 +08:00
2026-05-16 09:24:40 +08:00
2026-04-26 11:08:11 +08:00
2026-09-14 07:25:41 +08:00
2026-08-13 23:55:30 +08:00
2026-08-13 23:55:30 +08:00
2026-09-03 08:17:26 +08:00
2026-09-12 21:01:46 +08:00
2026-08-23 09:57:12 +08:00
2026-07-17 14:49:51 +08:00
2026-07-17 14:49:51 +08:00
2026-09-08 17:00:26 +08:00
2026-07-23 22:51:35 +08:00
2026-07-23 22:51:35 +08:00
2026-08-22 16:53:32 +08:00
2026-06-24 13:57:12 +08:00
2026-09-09 08:45:20 +08:00
2026-08-25 07:49:38 +08:00
2026-09-01 22:36:31 +08:00
2026-09-12 21:09:05 +08:00
2026-09-03 08:17:26 +08:00
2026-09-12 16:20:31 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-08-29 14:36:38 +08:00
2026-07-27 11:47:49 +08:00
2026-09-08 19:21:57 +08:00
2026-09-03 08:17:26 +08:00
2026-09-16 17:14:38 +08:00
2026-07-26 08:00:48 +08:00
2026-08-30 21:25:05 +08:00
2026-09-03 08:04:21 +08:00
2026-09-15 08:14:42 +08:00
2026-08-01 22:19:59 +08:00
2026-07-28 07:56:04 +08:00
2026-08-14 12:35:24 +08:00
2026-08-05 08:29:22 +08:00
2026-08-31 23:18:34 +08:00
2026-08-02 22:25:02 +08:00
2026-08-02 22:25:02 +08:00
2026-07-14 07:37:59 +08:00
2026-06-16 23:04:39 +08:00
2026-06-18 10:15:31 +08:00
2026-07-12 08:54:03 +08:00
2026-09-16 16:33:47 +08:00
2026-08-14 23:29:04 +08:00
2026-07-17 14:49:51 +08:00
2026-06-18 10:45:33 +08:00
2026-09-16 22:20:16 +08:00
2026-09-17 21:48:40 +08:00
2026-08-02 22:25:02 +08:00
2026-08-02 22:25:02 +08:00
2026-08-02 22:25:02 +08:00
2026-08-02 22:25:02 +08:00
2026-07-28 22:12:27 +08:00
2026-08-23 09:57:12 +08:00
2026-07-26 10:44:50 +08:00
2026-09-08 19:21:57 +08:00
2026-09-18 16:46:19 +08:00
2026-09-14 18:17:54 +08:00
2026-07-12 08:15:32 +08:00
2026-08-11 21:04:55 +08:00
2026-08-13 23:55:30 +08:00
2026-08-24 07:37:35 +08:00
2026-09-15 22:22:12 +08:00
2026-03-30 07:41:18 +08:00
2026-04-25 19:40:06 +08:00
2026-04-07 18:21:22 +08:00
2026-07-22 14:02:56 +08:00
2026-09-01 16:49:39 +08:00
2026-09-02 11:54:40 +08:00
2026-07-29 22:16:48 +08:00
2026-05-04 09:56:16 +08:00
2026-09-17 08:45:29 +08:00
2026-09-17 21:10:18 +08:00
2026-08-30 15:37:38 +08:00
2026-08-24 21:48:37 +08:00
2026-06-10 21:36:25 +08:00
2026-08-23 15:08:39 +08:00
2026-09-14 06:55:57 +08:00
2026-09-12 11:24:46 +08:00
2026-07-29 22:24:04 +08:00
2026-08-23 09:57:12 +08:00
2026-09-14 18:17:54 +08:00
2026-09-15 08:25:08 +08:00
2026-09-14 15:05:30 +08:00
2026-09-15 08:25:08 +08:00
2026-09-14 10:51:01 +08:00
2026-09-16 15:37:57 +08:00
2026-04-26 11:05:47 +08:00
2026-07-05 09:54:55 +08:00
2026-03-29 15:31:18 +08:00
2026-09-17 09:35:50 +08:00
2026-09-17 22:10:52 +08:00
2026-08-13 23:55:30 +08:00
2026-09-14 18:17:54 +08:00
2026-08-12 09:25:05 +08:00
2026-08-08 21:07:55 +08:00
2026-09-17 22:06:03 +08:00
2026-08-30 21:25:05 +08:00
2026-08-17 08:20:42 +08:00
2026-07-13 17:57:34 +08:00
2026-06-02 22:43:22 +08:00
2026-06-05 15:21:41 +08:00
2026-07-12 00:17:11 +08:00
2026-07-04 23:09:29 +08:00
2026-06-02 22:43:22 +08:00
2026-07-01 22:49:17 +08:00
2026-09-08 16:11:49 +08:00
2026-07-22 08:33:29 +08:00
2026-07-28 23:21:23 +08:00
2026-09-14 06:55:57 +08:00
2026-07-22 13:55:40 +08:00
2026-07-29 22:33:45 +08:00
2026-09-17 14:53:54 +08:00
2026-07-29 22:33:45 +08:00
2026-09-14 06:55:57 +08:00
2026-09-14 11:01:31 +08:00
2026-06-12 15:24:58 +08:00
2026-09-16 15:29:14 +08:00
2026-09-14 06:55:57 +08:00
2026-08-18 23:14:17 +08:00
2026-09-08 23:29:52 +08:00
2026-09-08 16:11:49 +08:00
2026-09-18 11:32:04 +08:00
2026-08-11 21:52:12 +08:00
2026-09-16 17:14:38 +08:00
2026-04-26 11:09:56 +08:00
2026-09-02 21:05:23 +08:00
2026-04-08 17:13:39 +08:00
2026-09-12 10:59:31 +08:00
2026-09-16 21:18:05 +08:00
2026-08-04 22:33:26 +08:00
2026-08-23 09:57:12 +08:00
2026-09-01 16:49:39 +08:00
2026-08-11 16:33:22 +08:00
2026-09-12 15:59:41 +08:00
2026-09-16 21:18:05 +08:00
2026-08-04 22:33:26 +08:00
2026-08-04 22:33:26 +08:00
2026-08-23 09:57:12 +08:00
2026-09-14 11:01:31 +08:00
2026-09-05 14:03:00 +08:00
2026-08-04 22:33:26 +08:00
2026-08-13 23:55:30 +08:00
2026-08-29 23:50:45 +08:00
2026-08-11 16:33:22 +08:00
2026-08-11 16:33:22 +08:00
2026-08-11 16:33:22 +08:00
2026-09-06 08:39:26 +08:00
2026-08-12 09:25:05 +08:00
2026-08-23 15:08:39 +08:00
2026-09-12 11:24:46 +08:00
2026-07-05 09:54:55 +08:00
2026-09-16 15:37:57 +08:00
2026-09-16 15:56:25 +08:00
2026-09-14 11:01:31 +08:00
2026-07-02 08:24:15 +08:00
2026-09-16 18:46:18 +08:00
2026-09-12 12:50:22 +08:00
2026-09-12 14:28:15 +08:00
2026-09-08 17:06:28 +08:00
2026-07-19 22:12:30 +08:00
2026-09-13 17:23:04 +08:00
2026-07-31 21:57:22 +08:00
2026-07-22 08:33:29 +08:00
2026-07-29 00:09:02 +08:00
2026-08-13 23:55:30 +08:00
2026-09-04 23:26:53 +08:00
2026-09-01 22:04:17 +08:00
2026-09-12 07:35:07 +08:00
2026-09-14 11:01:31 +08:00
2026-08-13 23:55:30 +08:00
2026-09-17 21:26:52 +08:00
2026-08-13 23:55:30 +08:00
2026-08-14 23:50:40 +08:00
2026-08-13 23:55:30 +08:00
2026-09-16 18:46:18 +08:00
2026-09-12 14:32:05 +08:00
2026-09-14 06:55:57 +08:00
2026-07-04 22:56:24 +08:00
2026-07-04 22:56:24 +08:00
2026-07-04 22:56:24 +08:00
2026-08-14 12:35:24 +08:00
2026-07-04 22:56:24 +08:00
2026-07-14 22:56:50 +08:00
2026-07-04 22:56:24 +08:00
2026-09-17 07:45:19 +08:00
2026-07-16 09:12:29 +08:00
2026-07-23 14:32:49 +08:00
2026-07-15 22:30:34 +08:00
2026-09-16 21:30:57 +08:00
2026-06-21 15:55:10 +08:00
2026-08-23 09:57:12 +08:00
2026-03-14 22:55:52 +08:00
2026-08-23 15:46:10 +08:00
2026-08-23 15:08:39 +08:00
2026-09-13 20:28:32 +08:00
2026-09-06 09:01:33 +08:00
2026-07-27 14:05:31 +08:00
2026-07-10 11:08:30 +08:00
2026-07-27 23:07:40 +08:00
2026-03-26 14:20:18 +08:00
2026-09-09 16:31:41 +08:00
2026-06-28 16:10:44 +08:00
2026-07-08 17:10:27 +08:00
2026-09-16 18:46:18 +08:00
2026-07-04 13:54:04 +08:00
2026-06-17 15:29:22 +08:00
2026-08-17 08:16:14 +08:00
2026-09-02 14:19:37 +08:00
2026-08-23 15:00:37 +08:00
2026-09-15 07:28:24 +08:00
2026-09-16 15:18:29 +08:00
2026-09-14 18:24:51 +08:00
2026-08-15 21:20:34 +08:00
2026-08-15 21:20:34 +08:00
2026-08-16 23:54:06 +08:00
2026-08-15 21:20:34 +08:00
2026-07-28 22:54:44 +08:00
2026-09-16 18:39:24 +08:00
2026-09-14 18:17:54 +08:00
2026-09-18 11:32:04 +08:00
2026-07-28 23:21:23 +08:00
2026-09-06 10:21:58 +08:00
2026-09-06 10:21:58 +08:00
2026-09-12 07:25:19 +08:00
2026-09-18 07:29:34 +08:00
2026-04-11 16:52:10 +08:00
2026-07-20 23:33:09 +08:00
2026-09-18 11:30:11 +08:00
2026-09-15 07:31:03 +08:00
2026-09-14 07:30:34 +08:00
2026-09-14 14:05:21 +08:00
2026-07-13 00:01:22 +08:00
2026-09-14 11:01:31 +08:00
2026-09-16 16:33:47 +08:00
2026-04-30 22:27:14 +08:00
2026-05-07 16:15:15 +08:00
2026-09-17 09:36:55 +08:00
2026-07-26 14:43:08 +08:00
2026-08-29 14:54:02 +08:00
2026-08-24 11:04:23 +08:00
2026-08-24 11:04:23 +08:00
2026-09-04 11:30:36 +08:00
2026-09-17 11:35:13 +08:00
2026-09-01 23:24:49 +08:00
2026-09-01 23:24:49 +08:00
2026-04-25 09:18:13 +08:00
2026-09-18 08:03:37 +08:00
2026-08-31 15:07:30 +08:00
2026-08-31 15:07:30 +08:00
2026-09-14 18:07:21 +08:00
2026-07-09 16:26:31 +08:00
2026-07-09 16:26:31 +08:00
2026-07-28 22:59:14 +08:00
2026-09-13 17:13:45 +08:00
2026-09-13 17:13:45 +08:00
2026-08-05 08:56:18 +08:00
2026-09-04 19:34:15 +08:00
2026-08-15 14:26:38 +08:00
2026-08-15 14:26:38 +08:00
2026-08-27 10:42:42 +08:00
2026-08-15 14:26:38 +08:00
2026-09-09 15:52:09 +08:00
2026-09-09 15:52:09 +08:00
2026-08-15 14:26:38 +08:00
2026-08-23 15:30:21 +08:00
2026-08-28 10:37:01 +08:00
2026-08-15 14:26:38 +08:00
2026-08-15 14:26:38 +08:00
2026-08-24 06:57:55 +08:00
2026-08-15 14:26:38 +08:00
2026-07-14 09:49:43 +08:00
2026-09-01 23:24:49 +08:00
2026-09-06 09:01:33 +08:00
2026-09-03 08:00:25 +08:00
2026-08-01 08:39:28 +08:00
2026-08-17 08:20:42 +08:00
2026-09-14 07:22:38 +08:00
2026-09-18 11:32:04 +08:00
2026-07-26 21:16:36 +08:00
2026-07-22 07:46:03 +08:00
2026-09-01 16:49:39 +08:00
2026-07-15 11:21:04 +08:00
2026-07-26 21:16:36 +08:00
2026-09-03 08:00:25 +08:00
2026-09-18 11:32:04 +08:00
2026-09-18 11:32:04 +08:00
2026-07-27 23:17:18 +08:00
2026-07-31 18:06:45 +08:00
2026-08-01 08:39:28 +08:00
2026-07-15 11:21:04 +08:00
2026-08-17 08:20:42 +08:00
2026-07-22 07:46:03 +08:00
2026-07-22 07:46:03 +08:00
2026-07-22 07:46:03 +08:00
2026-09-09 15:52:09 +08:00
2026-08-17 08:20:42 +08:00
2026-07-15 11:21:04 +08:00
2026-09-01 16:49:39 +08:00
2026-09-01 15:26:33 +08:00
2026-07-26 21:16:36 +08:00
2026-08-17 08:20:42 +08:00
2026-09-18 11:32:04 +08:00
2026-09-06 22:50:58 +08:00
2026-09-18 07:29:34 +08:00
2026-09-09 15:52:09 +08:00
2026-09-09 15:52:09 +08:00
2026-07-27 23:07:40 +08:00
2026-09-09 15:52:09 +08:00
2026-08-29 23:50:45 +08:00
2026-09-03 08:17:26 +08:00
2026-09-08 17:00:26 +08:00
2026-09-09 15:52:09 +08:00
2026-09-12 07:35:07 +08:00
2026-09-14 07:25:41 +08:00
2026-09-16 21:18:05 +08:00
2026-09-18 10:48:26 +08:00
2026-09-18 10:48:26 +08:00
2026-07-04 13:54:04 +08:00
2026-09-05 14:10:18 +08:00
2026-07-31 21:57:22 +08:00
2026-09-18 07:29:34 +08:00
2026-09-18 07:29:34 +08:00
2026-07-26 14:43:08 +08:00
2026-09-16 22:07:42 +08:00
2026-09-15 07:14:35 +08:00
2026-08-01 22:34:11 +08:00
2026-07-31 17:55:24 +08:00
2026-07-27 23:07:40 +08:00
2026-08-14 23:50:40 +08:00
2026-09-13 18:16:22 +08:00
2026-06-22 18:55:20 +08:00
2026-08-01 22:19:59 +08:00
2026-09-18 09:03:55 +08:00
2026-06-21 15:47:53 +08:00
2026-09-01 15:51:37 +08:00
2026-09-16 17:14:38 +08:00
2026-08-11 13:56:02 +08:00
2026-09-06 09:01:33 +08:00
2026-07-11 16:05:30 +08:00
2026-09-17 11:35:13 +08:00
2026-09-16 18:46:18 +08:00
2026-09-18 07:29:34 +08:00
2026-05-28 18:24:32 +08:00
2026-06-08 22:04:38 +08:00
2026-03-26 15:07:05 +08:00
2026-06-09 18:01:43 +08:00
2026-07-26 08:09:17 +08:00
2026-06-24 13:57:12 +08:00
2026-09-09 15:52:09 +08:00
2026-06-24 13:57:12 +08:00
2026-09-09 15:52:09 +08:00
2026-06-24 13:57:12 +08:00
2026-07-30 13:51:17 +08:00
2026-09-09 15:52:09 +08:00
2026-07-30 13:51:17 +08:00
2026-09-12 07:35:07 +08:00
2026-08-23 09:57:12 +08:00
2026-09-09 14:56:31 +08:00
2026-05-21 16:22:09 +08:00
2026-08-29 23:50:45 +08:00
2026-07-30 13:51:17 +08:00
2026-09-11 18:41:24 +08:00
2026-07-30 13:51:17 +08:00
2026-08-05 07:43:54 +08:00
2026-08-05 07:43:54 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-18 09:05:26 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 18:46:18 +08:00
2026-09-08 17:00:26 +08:00
2026-09-16 18:46:18 +08:00
2026-07-20 07:24:34 +08:00
2026-04-10 20:40:30 +08:00
2026-08-31 14:35:08 +08:00
2026-09-14 11:10:41 +08:00
2026-09-17 07:45:19 +08:00
2026-08-25 16:57:55 +08:00
2026-08-25 16:57:55 +08:00
2026-07-21 09:23:14 +08:00
2026-09-13 19:55:58 +08:00
2026-09-13 18:04:51 +08:00
2026-09-15 08:25:08 +08:00
2026-07-30 07:53:10 +08:00
2026-08-13 21:20:49 +08:00
2026-09-16 23:57:38 +08:00
2026-03-14 22:55:52 +08:00
2026-08-29 16:56:56 +08:00
2026-03-14 22:55:52 +08:00
2026-09-01 16:49:39 +08:00
2026-09-16 17:14:38 +08:00
2026-09-17 07:45:19 +08:00
2026-09-14 15:38:34 +08:00
2026-06-08 17:32:41 +08:00
2026-06-09 21:58:31 +08:00
2026-09-14 11:10:41 +08:00
2026-07-11 15:58:07 +08:00
2026-08-27 14:59:31 +08:00
2026-08-25 08:22:57 +08:00
2026-06-24 17:47:04 +08:00
2026-07-02 07:43:09 +08:00
2026-04-26 15:09:25 +08:00
2026-09-01 22:04:17 +08:00
2026-09-15 08:45:08 +08:00
2026-09-16 18:46:18 +08:00
2026-09-16 21:18:05 +08:00
2026-09-16 18:46:18 +08:00
2026-09-17 07:38:38 +08:00
2026-09-01 16:49:39 +08:00
2026-05-21 14:48:28 +08:00
2026-09-13 20:28:32 +08:00
2026-07-27 22:27:16 +08:00
2026-08-05 08:56:18 +08:00
2026-09-14 18:17:54 +08:00
2026-08-22 16:53:32 +08:00
2026-09-16 18:46:18 +08:00
2026-08-01 19:42:44 +08:00
2026-06-24 10:24:36 +08:00
2026-09-12 07:41:24 +08:00
2026-07-22 08:33:29 +08:00
2026-07-19 22:12:30 +08:00
2026-07-23 22:56:12 +08:00
2026-09-15 22:22:12 +08:00
2026-05-22 21:20:28 +08:00
2026-08-01 21:44:34 +08:00
2026-09-10 15:01:56 +08:00
2026-08-30 10:30:34 +08:00
2026-09-17 22:33:18 +08:00
2026-09-02 21:05:23 +08:00
2026-06-03 22:02:27 +08:00
2026-09-04 23:46:57 +08:00
2026-09-04 23:46:57 +08:00
2026-09-04 23:46:57 +08:00
2026-04-09 17:21:23 +08:00
2026-09-04 23:46:57 +08:00
2026-08-24 15:27:33 +08:00
2026-09-14 14:05:21 +08:00
2026-06-25 08:06:17 +08:00
2026-09-16 16:00:23 +08:00
2026-09-12 10:54:39 +08:00
2026-09-14 14:05:21 +08:00
2026-07-04 13:54:04 +08:00
2026-06-12 10:20:38 +08:00
2026-09-12 07:35:07 +08:00
2026-07-04 21:51:57 +08:00
2026-09-12 14:59:04 +08:00
2026-08-24 15:38:32 +08:00
2026-07-04 21:51:57 +08:00
2026-08-24 15:38:32 +08:00
2026-09-12 07:35:07 +08:00
2026-09-16 19:56:01 +08:00
2026-08-24 15:38:32 +08:00
2026-09-10 16:46:01 +08:00
2026-07-04 21:51:57 +08:00
2026-09-14 14:09:27 +08:00
2026-09-10 16:46:01 +08:00
2026-09-12 07:35:07 +08:00
2026-09-12 07:35:07 +08:00
2026-09-12 07:35:07 +08:00
2026-08-24 07:09:08 +08:00
2026-09-16 21:18:05 +08:00
2026-08-30 21:25:05 +08:00
2026-08-24 21:27:43 +08:00
2026-06-19 11:23:07 +08:00
2026-03-26 14:20:18 +08:00
2026-07-21 08:15:33 +08:00
2026-08-28 10:30:30 +08:00
2026-08-28 10:44:30 +08:00
2026-09-14 06:55:57 +08:00
2026-09-14 06:55:57 +08:00
2026-07-07 23:09:06 +08:00
2026-07-23 08:03:21 +08:00
2026-05-12 23:18:54 +08:00
2026-07-23 08:03:21 +08:00
2026-09-17 22:00:22 +08:00
2026-08-28 22:24:10 +08:00
2026-06-19 21:57:03 +08:00
2026-09-17 07:59:58 +08:00
2026-07-04 11:27:19 +08:00
2026-07-04 11:27:19 +08:00
2026-09-02 17:05:36 +08:00
2026-09-17 07:59:58 +08:00
2026-09-12 14:32:05 +08:00
2026-07-31 17:55:24 +08:00
2026-07-13 10:40:22 +08:00
2026-09-08 09:21:38 +08:00
2026-09-05 14:03:00 +08:00
2026-08-31 14:35:08 +08:00
2026-09-14 10:54:34 +08:00
2026-09-14 21:23:58 +08:00
2026-09-14 11:01:31 +08:00
2026-07-11 15:58:07 +08:00
2026-08-25 19:46:04 +08:00
2026-08-28 08:58:59 +08:00
2026-03-25 16:28:33 +08:00
2026-07-16 14:12:02 +08:00
2026-09-18 08:02:52 +08:00
2026-09-14 21:23:58 +08:00
2026-09-18 08:02:52 +08:00
2026-08-28 08:58:59 +08:00
2026-08-28 08:58:59 +08:00
2026-07-17 23:22:16 +08:00
2026-09-18 08:02:52 +08:00
2026-09-02 00:33:21 +08:00
2026-09-14 21:23:58 +08:00
2026-06-18 10:09:46 +08:00
2026-07-08 21:58:33 +08:00
2026-09-18 07:48:24 +08:00
2026-09-08 10:50:03 +08:00
2026-07-28 22:59:14 +08:00
2026-03-30 16:02:23 +08:00
2026-09-08 14:40:05 +08:00
2026-07-31 17:25:07 +08:00
2026-07-22 09:20:54 +08:00
2026-08-30 10:46:01 +08:00
2026-09-01 15:51:37 +08:00
2026-09-08 16:11:49 +08:00
2026-08-25 07:49:38 +08:00
2026-09-12 07:41:24 +08:00
2026-08-25 07:49:38 +08:00
2026-08-25 07:49:38 +08:00
2026-09-16 22:05:20 +08:00
2026-06-14 10:30:45 +08:00
2026-09-12 16:20:31 +08:00
2026-06-08 23:17:22 +08:00
2026-07-14 08:14:21 +08:00
2026-09-02 11:54:40 +08:00
2026-09-18 14:23:06 +08:00
2026-09-15 22:22:12 +08:00
2026-08-24 11:04:23 +08:00
2026-08-30 11:39:25 +08:00
2026-07-30 07:21:55 +08:00
2026-09-18 14:27:33 +08:00
2026-05-02 06:37:49 +08:00
2026-09-01 16:13:41 +08:00
2026-07-11 15:41:57 +08:00
2026-07-13 19:26:07 +08:00
2026-06-19 21:42:42 +08:00
2026-09-17 09:05:25 +08:00
2026-08-24 11:04:23 +08:00
2026-07-28 19:35:21 +08:00
2026-09-15 22:10:39 +08:00
2026-09-08 16:00:45 +08:00
2026-07-27 11:47:49 +08:00
2026-07-27 11:47:49 +08:00
2026-08-01 19:42:44 +08:00
2026-09-14 06:55:57 +08:00
2026-09-14 11:01:31 +08:00
2026-08-23 09:57:12 +08:00
2026-09-12 21:01:46 +08:00
2026-09-15 08:45:08 +08:00
2026-05-21 21:18:10 +08:00
2026-09-18 07:25:49 +08:00
2026-08-23 10:27:19 +08:00
2026-08-27 18:12:05 +08:00
2026-09-16 17:14:38 +08:00
2026-09-18 07:29:34 +08:00
2026-09-06 22:30:26 +08:00
2026-07-28 22:59:14 +08:00
2026-09-16 18:46:18 +08:00
2026-08-01 19:42:44 +08:00
2026-07-27 22:46:51 +08:00
2026-08-11 22:00:57 +08:00
2026-09-09 15:52:09 +08:00
2026-09-12 21:09:05 +08:00
2026-09-12 07:41:24 +08:00
2026-07-29 12:47:30 +08:00
2026-09-09 14:56:31 +08:00
2026-09-18 09:39:14 +08:00
2026-09-09 14:56:31 +08:00
2026-06-02 22:43:22 +08:00
2026-09-12 21:01:46 +08:00
2026-09-18 09:39:14 +08:00
2026-07-28 23:21:23 +08:00
2026-09-14 18:17:54 +08:00
2026-09-14 11:10:41 +08:00
2026-07-15 11:21:04 +08:00
2026-03-14 22:55:52 +08:00
2026-09-12 09:22:27 +08:00
2026-08-11 11:41:31 +08:00
2026-09-16 15:52:17 +08:00
2026-07-04 23:14:46 +08:00
2026-05-10 22:00:57 +08:00
2026-08-12 09:25:05 +08:00
2026-07-28 23:21:23 +08:00
2026-09-12 16:20:31 +08:00
2026-09-13 18:04:51 +08:00
2026-09-15 22:22:12 +08:00
2026-08-22 16:53:32 +08:00
2026-09-15 22:10:39 +08:00
2026-07-04 11:27:19 +08:00
2026-09-13 18:04:51 +08:00
2026-09-16 23:57:38 +08:00
2026-09-16 15:52:17 +08:00
2026-09-15 08:45:08 +08:00
2026-08-29 16:56:56 +08:00
2026-08-29 16:56:56 +08:00
2026-09-15 08:45:08 +08:00
2026-09-01 09:49:32 +08:00
2026-07-14 09:49:43 +08:00
2026-08-23 09:57:12 +08:00
2026-09-01 16:49:39 +08:00
2026-09-01 16:49:39 +08:00
2026-09-01 16:49:39 +08:00
2026-07-14 08:58:06 +08:00
2026-07-14 08:58:06 +08:00
2026-07-03 08:01:46 +08:00
2026-09-16 18:46:18 +08:00
2026-08-25 20:15:08 +08:00
2026-08-04 08:33:10 +08:00
2026-08-13 23:55:30 +08:00
2026-09-18 07:48:24 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-06-25 20:10:49 +08:00
2026-07-15 22:27:00 +08:00
2026-06-25 20:10:49 +08:00
2026-08-05 08:15:28 +08:00
2026-07-20 23:56:37 +08:00
2026-05-12 23:18:54 +08:00
2026-09-12 11:09:41 +08:00
2026-07-26 21:16:36 +08:00
2026-07-26 21:16:36 +08:00
2026-08-28 09:16:51 +08:00
2026-07-28 22:59:14 +08:00
2026-09-16 18:46:18 +08:00
2026-07-28 22:59:14 +08:00
2026-09-03 08:17:26 +08:00
2026-09-14 07:25:41 +08:00
2026-08-24 21:27:43 +08:00
2026-07-11 09:18:12 +08:00
2026-07-14 10:43:13 +08:00
2026-05-02 15:16:16 +08:00
2026-08-13 23:55:30 +08:00
2026-08-23 15:43:37 +08:00
2026-08-27 09:12:37 +08:00
2026-09-10 15:48:55 +08:00
2026-09-10 15:48:55 +08:00
2026-09-10 15:48:55 +08:00
2026-07-24 13:12:43 +08:00
2026-07-28 19:56:40 +08:00
2026-07-27 07:13:06 +08:00
2026-07-06 07:21:12 +08:00
2026-07-20 23:05:47 +08:00
2026-09-11 18:36:58 +08:00
2026-09-08 10:50:03 +08:00
2026-09-16 16:33:47 +08:00
2026-09-12 09:59:58 +08:00
2026-07-12 07:52:45 +08:00
2026-09-01 16:49:39 +08:00
2026-09-14 07:17:51 +08:00
2026-07-12 11:51:31 +08:00
2026-09-14 18:17:54 +08:00
2026-09-08 14:51:57 +08:00
2026-06-07 17:47:11 +08:00