From 41a21d20cdc086dbd7adaecbf05fc93429289253 Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr@nexedi.com>
Date: Sun, 31 Mar 2019 10:27:46 +0300
Subject: [PATCH] .

---
 wcfs/wcfs.go | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/wcfs/wcfs.go b/wcfs/wcfs.go
index 0c2c6a40..4dbf273c 100644
--- a/wcfs/wcfs.go
+++ b/wcfs/wcfs.go
@@ -1307,16 +1307,39 @@ func (wlink *WatchLink) setupWatch(ctx context.Context, foid zodb.Oid, at zodb.T
 		return fmt.Errorf("at is too far away back from head/at")
 	}
 
-	toPin := SetI64{} // f's blocks that have been changed after at
+	toPin := map[int64]zodb.Tid // blk -> @rev
 
 	// XXX f.δtail.Head() not neccessarily = head.At()
 	// (if f was not changed by a txn, f.δtail stays not updated)	XXX correct?
-	f.δtail.SliceByRev(at, f.δtail.Head())
-
+	//
+	// FIXME (!!!) since f.δtail does not have all changes to f, here we
+	// can be missing some pins we should be sending. (see wcfs_test.py for details)
+	for _, δ := range f.δtail.SliceByRev(at, f.δtail.Head()) {
+		for _, blk := range δ.Changev {
+			_, already := toPin[blk]
+			if already {
+				continue
+			}
 
+			// FIXME (!!!) again f.δtail can miss some entries
+			toPin[blk], _ = f.δtail.LastRevOf(blk, at)
+		}
+	}
 
+	wg, ctx := errgroup.WithContext(ctx)
+	for blk, rev := range toPin {
+		blk := blk
+		rev := rev
+		wg.Go(func() error {
+			return wlink.pin(ctx, blk, rev)
+		})
+	}
+	err = wg.Wait()
+	if err != nil {
+		panic(err)	// XXX
+	}
 
-	panic("TODO")
+	// XXX something else?
 }
 
 // Open serves /head/watch opens.
-- 
2.30.9