释放已解决的 DirectThread 请求事件
请求无 ID 时立即可清理,解决事件到达后解除对应 requested 事件 pin。
This commit is contained in:
@@ -152,6 +152,12 @@ impl DirectThreadManager {
|
||||
cleanable,
|
||||
});
|
||||
Self::mark_item_events_cleanable(thread, event.item_id.as_deref());
|
||||
if matches!(
|
||||
event.event_type.as_str(),
|
||||
"approval.resolved" | "request.resolved" | "ask.resolved"
|
||||
) {
|
||||
Self::mark_request_events_cleanable(thread, request_id(&event).as_deref());
|
||||
}
|
||||
self.evict(thread_id);
|
||||
event
|
||||
}
|
||||
@@ -266,10 +272,11 @@ impl DirectThreadManager {
|
||||
true
|
||||
}
|
||||
"approval.requested" | "request.requested" | "ask.requested" => {
|
||||
if let Some(request_id) = request_id(event) {
|
||||
thread.unresolved_requests.insert(request_id);
|
||||
let request_id = request_id(event);
|
||||
if let Some(request_id) = request_id.as_deref() {
|
||||
thread.unresolved_requests.insert(request_id.to_string());
|
||||
}
|
||||
false
|
||||
request_id.is_none()
|
||||
}
|
||||
"approval.resolved" | "request.resolved" | "ask.resolved" => {
|
||||
if let Some(request_id) = request_id(event) {
|
||||
@@ -316,6 +323,21 @@ impl DirectThreadManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_request_events_cleanable(thread: &mut ThreadState, resolved_request_id: Option<&str>) {
|
||||
let Some(resolved_request_id) = resolved_request_id else {
|
||||
return;
|
||||
};
|
||||
for stored in &mut thread.events {
|
||||
if matches!(
|
||||
stored.event.event_type.as_str(),
|
||||
"approval.requested" | "request.requested" | "ask.requested"
|
||||
) && request_id(&stored.event).as_deref() == Some(resolved_request_id)
|
||||
{
|
||||
stored.cleanable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn trim_prefix(thread: &mut ThreadState) {
|
||||
let min_cursor = thread
|
||||
.subscribers
|
||||
@@ -583,6 +605,34 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolved_request_releases_the_original_requested_event() {
|
||||
let mut manager = DirectThreadManager::with_limits(100, 100_000);
|
||||
manager.append(
|
||||
"thread-1",
|
||||
DirectThreadRawEventDraft {
|
||||
event_type: "approval.requested".to_string(),
|
||||
turn_id: "turn-1".to_string(),
|
||||
item_id: None,
|
||||
payload: serde_json::json!({"requestId": "request-1"}),
|
||||
},
|
||||
);
|
||||
let subscription = manager.subscribe("thread-1");
|
||||
manager.append(
|
||||
"thread-1",
|
||||
DirectThreadRawEventDraft {
|
||||
event_type: "approval.resolved".to_string(),
|
||||
turn_id: "turn-1".to_string(),
|
||||
item_id: None,
|
||||
payload: serde_json::json!({"requestId": "request-1"}),
|
||||
},
|
||||
);
|
||||
manager
|
||||
.consume(&subscription.subscription_id)
|
||||
.expect("consume resolution");
|
||||
assert_eq!(manager.thread_debug("thread-1").unwrap().0, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_completed_anchor_survives_empty_queue_for_new_subscriber() {
|
||||
let mut manager = DirectThreadManager::with_limits(100, 100_000);
|
||||
|
||||
Reference in New Issue
Block a user