mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-07 04:27:49 +01:00
filer.remote.sync: stamp a copy of the event entry
updateLocalEntry set the RemoteEntry and dropped the rename marker on the caller's entry before the RPC. A transient stamp failure retries the same event in place, which then read as already synced and skipped both the upload and the stamp. The stub filer now applies a successful update the way the filer does, since tests had relied on that shared object. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0a1b6c2944
commit
1f332e5866
2 files changed
+29
-1
No files matched your search
@@ -1243,6 +1243,7 @@ func updateLocalEntry(filerClient filer_pb.FilerClient, dir string, entry *filer
|
||||
remoteEntry = proto.Clone(remoteEntry).(*filer_pb.RemoteEntry)
|
||||
remoteEntry.LastLocalSyncTsNs = time.Now().UnixNano()
|
||||
expected := proto.Clone(entry).(*filer_pb.Entry)
|
||||
entry = proto.Clone(entry).(*filer_pb.Entry)
|
||||
entry.RemoteEntry = remoteEntry
|
||||
delete(entry.Extended, filer.ExtRemoteRenameSourceKey)
|
||||
err := filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
|
||||
@@ -456,6 +456,11 @@ func (c *stubFilerClient) UpdateEntry(_ context.Context, req *filer_pb.UpdateEnt
|
||||
if c.updateErr != nil {
|
||||
return &filer_pb.UpdateEntryResponse{}, c.updateErr
|
||||
}
|
||||
if key := req.Directory + "/" + req.Entry.GetName(); c.entries[key] != nil {
|
||||
c.entries[key] = req.Entry
|
||||
} else if c.entry != nil && c.entry.Name == req.Entry.GetName() {
|
||||
c.entry = req.Entry
|
||||
}
|
||||
return &filer_pb.UpdateEntryResponse{}, nil
|
||||
}
|
||||
|
||||
@@ -1549,6 +1554,28 @@ func TestDeleteEventAbsentRemoteObjectIsSuccess(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestUpdateLocalEntryLeavesTheEventEntryAlone: a transient stamp failure
|
||||
// retries the same event in place, so the event must still read as unsynced
|
||||
// and keep its rename source, or the retry skips the upload and the stamp.
|
||||
func TestUpdateLocalEntryLeavesTheEventEntryAlone(t *testing.T) {
|
||||
const dir = "/buckets/b/vol"
|
||||
event := entryWith("state.db", nil, chunk("3,01", "e1"))
|
||||
event.Extended = map[string][]byte{filer.ExtRemoteRenameSourceKey: []byte("src")}
|
||||
filerClient := &stubFilerClient{updateErr: status.Error(codes.Unavailable, "filer is shutting down")}
|
||||
if err := updateLocalEntry(filerClient, dir, event, &filer_pb.RemoteEntry{StorageName: "gcs", RemoteSize: 7}); err == nil {
|
||||
t.Fatal("err = nil, want the transient failure")
|
||||
}
|
||||
if event.RemoteEntry != nil || len(event.Extended[filer.ExtRemoteRenameSourceKey]) == 0 {
|
||||
t.Errorf("event entry = %v, want it untouched by the failed stamp", event)
|
||||
}
|
||||
if !shouldSendToRemote(event) {
|
||||
t.Error("shouldSendToRemote = false after a failed stamp: the in-place retry would skip the upload")
|
||||
}
|
||||
if sent := filerClient.updated.GetEntry(); sent.GetRemoteEntry() == nil || len(sent.GetExtended()[filer.ExtRemoteRenameSourceKey]) > 0 {
|
||||
t.Errorf("stamp request entry = %v, want the remote entry set and the rename source dropped", sent)
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpdateLocalEntrySkipsDeletedEntry: the stamp that follows an upload lands
|
||||
// on an entry a later event already deleted. The filer answers "not found"; the
|
||||
// delete's own event follows in the log, so the stamp is skipped rather than
|
||||
@@ -1834,7 +1861,7 @@ func TestCompleteRemoteOnlyRenameClearsThePendingSourceFirst(t *testing.T) {
|
||||
|
||||
t.Run("a marker still in place keeps the source", func(t *testing.T) {
|
||||
// the stamp did not land: the filer still has the marker
|
||||
filerClient := &stubFilerClient{entry: pending()}
|
||||
filerClient := &stubFilerClient{entry: pending(), updateErr: status.Error(codes.FailedPrecondition, "entry changed")}
|
||||
remote := &recordingRemote{objects: objects(), statETag: `"copy"`}
|
||||
if err := completeRemoteOnlyRename(filerClient, remote, "/buckets/b/dst", pending(), renameSource{path: "/buckets/b/src/a.jpg", loc: oldDest}, dest, ""); err == nil {
|
||||
t.Fatal("err = nil, want the event retried")
|
||||
|
||||
Reference in new issue
Block a user