Desk door: DeskForkTooLarge becomes the not-stored refusal fork_too_large (list only), text names fork id and order; schemas regenerated
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5f3319f4ad
commit
c2aef3bc58
5 changed files with 18 additions and 91 deletions
|
|
@ -152,13 +152,14 @@ pub struct ForkDeskAnswer {
|
|||
pub request_id: String,
|
||||
}
|
||||
|
||||
/// The three requests Huginn refuses without storing, by code.
|
||||
/// The refusals Huginn sends without storing, by code. `ForkTooLarge` is the list's alone.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ForkRefusalCode {
|
||||
ForkUnknown,
|
||||
BodyInvalid,
|
||||
RequestIdConflict,
|
||||
ForkTooLarge,
|
||||
}
|
||||
|
||||
/// `gamecult.fork.refusal.v0`. `error` is a fixed sentence, never an echo of what was sent;
|
||||
|
|
@ -382,6 +383,12 @@ fn fork_unknown() -> ForkRefusal {
|
|||
fork_refusal(ForkRefusalCode::ForkUnknown, "fork_unknown: no such fork".into())
|
||||
}
|
||||
|
||||
/// A list page whose first entry alone is past the page budget: names that fork and its `order`; a
|
||||
/// client continues with the cursor `c<order>` and has reached the end at order 0.
|
||||
fn fork_too_large(fork: &str, order: u64) -> ForkRefusal {
|
||||
fork_refusal(ForkRefusalCode::ForkTooLarge, format!("fork_too_large: fork {fork} at order {order} is past the page budget by itself; continue with cursor c{order}"))
|
||||
}
|
||||
|
||||
fn body_invalid(field: &str) -> ForkRefusal {
|
||||
fork_refusal(ForkRefusalCode::BodyInvalid, format!("body_invalid: the body does not satisfy gamecult.fork.answer_request.v0 ({field})"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ impl<S: MindStore> Mind<S> {
|
|||
/// A page holds at most `limit` entries (never more than 50) and stops short only when the next
|
||||
/// entry would push the encoded response past `DESK_PAGE_BUDGET` (the one `DESK_MAX_RESPONSE_BYTES`
|
||||
/// less the envelope margin); counts and stamp are unaffected. A page whose FIRST entry alone is past
|
||||
/// the budget is `MindRefusal::DeskForkTooLarge`, naming that fork and its order: the caller goes on
|
||||
/// the budget is the `fork_too_large` refusal, naming that fork and its order: the caller goes on
|
||||
/// with the cursor `c<order>`, which returns the forks below it, so no older fork is unreachable.
|
||||
/// The fork itself is still its whole entry on `desk_fork`. Nothing is dropped silently.
|
||||
///
|
||||
|
|
@ -384,7 +384,7 @@ impl<S: MindStore> Mind<S> {
|
|||
if bytes > DESK_PAGE_BUDGET {
|
||||
let list = held(&mut response);
|
||||
if list.forks.len() == 1 {
|
||||
return Ok(DeskResponse::Refused(MindRefusal::DeskForkTooLarge { fork: key.to_string(), order: *order, bytes: bytes as u64, limit: DESK_PAGE_BUDGET as u64 }));
|
||||
return Ok(DeskResponse::NotStored(fork_too_large(key, *order)));
|
||||
}
|
||||
list.forks.pop();
|
||||
list.next_cursor = before;
|
||||
|
|
@ -1061,9 +1061,11 @@ mod tests {
|
|||
assert_eq!(ids(&first), [fork(3)]);
|
||||
assert_eq!(first.next_cursor.map(ForkCursor::order), Some(2));
|
||||
let response = mind.desk_forks(&list(&LIST), None, first.next_cursor, limit(50));
|
||||
let DeskResponse::Refused(MindRefusal::DeskForkTooLarge { fork: named, order, bytes, limit: bound }) = response else { panic!("{response:?}") };
|
||||
assert_eq!((named, order, bound), (fork(2), 1, DESK_PAGE_BUDGET as u64));
|
||||
assert!(bytes > bound);
|
||||
let DeskResponse::NotStored(refusal) = response else { panic!("{response:?}") };
|
||||
assert_eq!(refusal.code, ForkRefusalCode::ForkTooLarge);
|
||||
let order = 1;
|
||||
assert_eq!(refusal.error, fork_too_large(&fork(2), order).error);
|
||||
assert!(refusal.error.contains(&fork(2)) && refusal.error.contains("order 1"), "{refusal:?}");
|
||||
// The order the refusal names is the order of the fork it names; its cursor goes on past it.
|
||||
assert_eq!(entry(mind.desk_fork(&list(&LIST), &fork(2))).0.card.order, order);
|
||||
let (rest, _) = page(mind.desk_forks(&list(&LIST), None, ForkCursor::new(order), limit(50)));
|
||||
|
|
|
|||
|
|
@ -109,11 +109,6 @@ pub enum MindRefusal {
|
|||
/// truncated or paginated on its behalf. The daemon owns it and its
|
||||
/// deferral bound decides it; no rule of the mind is involved.
|
||||
ResponseTooLarge { bytes: u64, limit: u64 },
|
||||
/// A desk page whose first entry alone is past the page budget: `fork` is that fork, `order` its
|
||||
/// rank (a caller goes on past it with the cursor `c<order>`, which returns the forks below it),
|
||||
/// `bytes` what the page holding it would encode to (without the envelope) and `limit` the page
|
||||
/// budget it exceeds. Raised by the mind's page fill, which is why it is not `ResponseTooLarge`.
|
||||
DeskForkTooLarge { fork: String, order: u64, bytes: u64, limit: u64 },
|
||||
/// A selection the substrate or the organ's value door refused: `field`
|
||||
/// is the selection field the client sent, `value` the offending part.
|
||||
SelectionInvalid { field: String, value: Option<String>, message: String },
|
||||
|
|
|
|||
|
|
@ -471,12 +471,13 @@
|
|||
]
|
||||
},
|
||||
"ForkRefusalCode": {
|
||||
"description": "The three requests Huginn refuses without storing, by code.",
|
||||
"description": "The refusals Huginn sends without storing, by code. `ForkTooLarge` is the list's alone.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"fork_unknown",
|
||||
"body_invalid",
|
||||
"request_id_conflict"
|
||||
"request_id_conflict",
|
||||
"fork_too_large"
|
||||
]
|
||||
},
|
||||
"ListSchema": {
|
||||
|
|
@ -1562,45 +1563,6 @@
|
|||
"ResponseTooLarge"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A desk page whose first entry alone is past the page budget: `fork` is that fork, `order` its\nrank (a caller goes on past it with the cursor `c<order>`, which returns the forks below it),\n`bytes` what the page holding it would encode to (without the envelope) and `limit` the page\nbudget it exceeds. Raised by the mind's page fill, which is why it is not `ResponseTooLarge`.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"DeskForkTooLarge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bytes": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"fork": {
|
||||
"type": "string"
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"order": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fork",
|
||||
"order",
|
||||
"bytes",
|
||||
"limit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"DeskForkTooLarge"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A selection the substrate or the organ's value door refused: `field`\nis the selection field the client sent, `value` the offending part.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -2059,45 +2059,6 @@
|
|||
"ResponseTooLarge"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A desk page whose first entry alone is past the page budget: `fork` is that fork, `order` its\nrank (a caller goes on past it with the cursor `c<order>`, which returns the forks below it),\n`bytes` what the page holding it would encode to (without the envelope) and `limit` the page\nbudget it exceeds. Raised by the mind's page fill, which is why it is not `ResponseTooLarge`.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"DeskForkTooLarge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bytes": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"fork": {
|
||||
"type": "string"
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"order": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fork",
|
||||
"order",
|
||||
"bytes",
|
||||
"limit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"DeskForkTooLarge"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A selection the substrate or the organ's value door refused: `field`\nis the selection field the client sent, `value` the offending part.",
|
||||
"type": "object",
|
||||
|
|
|
|||
Loading…
Reference in a new issue