feat: persist and transfer script command payloads
This commit is contained in:
@@ -102,7 +102,7 @@ func (store *Store) AppendScriptChunk(ctx context.Context, issueUUID domain.UUID
|
||||
if err != nil {
|
||||
return ScriptStatus{}, err
|
||||
}
|
||||
if row.Committed {
|
||||
if row.Committed && offset >= row.ReceivedBytes {
|
||||
return ScriptStatus{}, ErrScriptTerminal
|
||||
}
|
||||
if offset > row.ReceivedBytes {
|
||||
@@ -123,8 +123,17 @@ func (store *Store) AppendScriptChunk(ctx context.Context, issueUUID domain.UUID
|
||||
if end > row.ReceivedBytes || !bytes.Equal(raw[offset:end], data) {
|
||||
return ScriptStatus{}, ErrScriptOverlap
|
||||
}
|
||||
// A reconnect can replay a chunk after the client has already committed
|
||||
// the complete script. Exact byte-for-byte replays are safe and must be
|
||||
// idempotent; a new byte after commit remains forbidden.
|
||||
if row.Committed {
|
||||
return ScriptStatus{ReceivedBytes: row.ReceivedBytes, Committed: true, Duplicate: true}, tx.Commit()
|
||||
}
|
||||
return ScriptStatus{ReceivedBytes: row.ReceivedBytes, Duplicate: true}, tx.Commit()
|
||||
}
|
||||
if row.Committed {
|
||||
return ScriptStatus{}, ErrScriptTerminal
|
||||
}
|
||||
updatedRaw := append(raw, data...)
|
||||
stored, err := compressScript(updatedRaw)
|
||||
if err != nil {
|
||||
|
||||
@@ -63,6 +63,10 @@ func TestScriptUploadDurableExactReplayAndCommit_HP_SCRIPT_01(t *testing.T) {
|
||||
if err != nil || !duplicate.Duplicate || !duplicate.Committed {
|
||||
t.Fatalf("ScriptCommit replay = %#v, %v", duplicate, err)
|
||||
}
|
||||
duplicate, err = store.AppendScriptChunk(ctx, issue, 0, raw[:len(first)], sha256.Sum256(raw[:len(first)]))
|
||||
if err != nil || !duplicate.Duplicate || !duplicate.Committed || duplicate.ReceivedBytes != uint64(len(raw)) {
|
||||
t.Fatalf("post-commit ScriptChunk replay = %#v, %v", duplicate, err)
|
||||
}
|
||||
if _, err := store.AppendScriptChunk(ctx, issue, uint64(len(raw)), []byte("!"), sha256.Sum256([]byte("!"))); !errors.Is(err, ErrScriptTerminal) {
|
||||
t.Fatalf("post-commit chunk error = %v, want ErrScriptTerminal", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user