chiark / gitweb /
try map error back to update
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 3 Sep 2020 21:21:56 +0000 (22:21 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 3 Sep 2020 21:21:56 +0000 (22:21 +0100)
src/updates.rs
templates/script.ts

index 71544b6aaca043af64225b660a9bf69f3194b7a3..61a2edcf30938d3605c7ccb7617906d958f880a5 100644 (file)
@@ -85,7 +85,7 @@ enum TransmitUpdateEntry<'u> {
   },
   Piece {
     piece : VisiblePieceId,
-    op : &'u PieceUpdateOp<PreparedPieceState>,
+    op : PieceUpdateOp<&'u PreparedPieceState>,
   },
   SetTableSize(Pos),
   Log (&'u LogEntry),
@@ -164,6 +164,16 @@ impl<NS> PieceUpdateOp<NS> {
       SetZLevel(zl) => SetZLevel(zl),
     })
   }
+  pub fn map_ref_new_state(&self) -> PieceUpdateOp<&NS> {
+    use PieceUpdateOp::*;
+    match self {
+      Delete() => Delete(),
+      Insert(ns) => Insert(ns),
+      Modify(ns) => Modify(ns),
+      Move(pos) => Move(*pos),
+      SetZLevel(zl) => SetZLevel(*zl),
+    }
+  }
   pub fn map_new_state<NS2,F: FnOnce(NS) -> NS2>(self, f:F)
                             -> PieceUpdateOp<NS2> {
     #[derive(Error,Debug)]
@@ -336,29 +346,36 @@ impl<'r> Drop for PrepareUpdatesBuffer<'r> {
 
 impl PreparedUpdate {
   pub fn for_transmit(&self, dest : ClientId) -> TransmitUpdate {
+    type ESVU = ErrorSignaledViaUpdate;
+    type PUE = PreparedUpdateEntry;
+    type TUE<'u> = TransmitUpdateEntry<'u>;
     let mut ents = vec![];
     for u in &self.us {
-      type Prep = PreparedUpdateEntry;
 eprintln!("FOR_TRANSMIT TO={:?} {:?}", dest, &u);
       let ue = match u {
-        &Prep::Piece
-        { piece, client, sameclient_cseq : cseq, ref op }
+        &PUE::Piece { piece, client, sameclient_cseq : cseq, ref op }
         if client == dest => {
           let zg = op.new_z_generation();
-          TransmitUpdateEntry::Recorded { piece, cseq, zg }
+          TUE::Recorded { piece, cseq, zg }
         },
-        &PreparedUpdateEntry::Piece { piece, ref op, .. } => {
-          TransmitUpdateEntry::Piece { piece, op }
+        &PUE::Piece { piece, ref op, .. } => {
+          TUE::Piece { piece, op: op.map_ref_new_state() }
         },
-        PreparedUpdateEntry::Log(logent) => {
-          TransmitUpdateEntry::Log(&logent)
+        PUE::Log(logent) => {
+          TUE::Log(&logent)
         },
-        &PreparedUpdateEntry::SetTableSize(size) => {
-          TransmitUpdateEntry::SetTableSize(size)
+        &PUE::SetTableSize(size) => {
+          TUE::SetTableSize(size)
         },
-        PreparedUpdateEntry::Error(c, e) => {
-          if let Some(c) = c { if *c != dest { continue } }
-          TransmitUpdateEntry::Error(e)
+        PUE::Error(c, e) => {
+          if *c == None || *c == Some(dest) {
+            TUE::Error(e)
+          } else if let &ESVU::PieceOpError { piece, ref state, .. } = e {
+            let op = PieceUpdateOp::Modify(state);
+            TUE::Piece { piece, op }
+          } else {
+            continue
+          }
         }
       };
       ents.push(ue);
index 5ea30b8e9ffb04f6d8909a976fab88e9bd3ff0f3..bd985797deabd8aa2fd746043a5b7d2858f77e8e 100644 (file)
@@ -445,6 +445,8 @@ pieceops.Modify = <PieceHandler>function
 
 piece_error_handlers.PosOffTable = <PieceErrorHandler>function()
 { return true ; }
+piece_error_handlers.Conflict = <PieceErrorHandler>function()
+{ return true ; }
 
 function piece_modify(piece: PieceId, p: PieceInfo, info: PieceStateMessage,
                      conflict_expected: boolean) {