fix(publish): require submit marker before platform write
Desktop Client Build / Resolve Build Metadata (push) Successful in 20s
Frontend CI / Frontend (push) Successful in 2m57s
Desktop Client Build / Build Desktop Client (push) Successful in 25m11s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 34s
Backend CI / Backend (push) Successful in 50m56s
Desktop Client Build / Resolve Build Metadata (push) Successful in 20s
Frontend CI / Frontend (push) Successful in 2m57s
Desktop Client Build / Build Desktop Client (push) Successful in 25m11s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 34s
Backend CI / Backend (push) Successful in 50m56s
This commit is contained in:
@@ -722,8 +722,9 @@ func (s *DesktopTaskService) Extend(ctx context.Context, client *repository.Desk
|
||||
// MarkPublishSubmitStarted records a durable intent marker right before the client performs the
|
||||
// irreversible platform submit POST. Lease-recovery uses it to avoid silently re-posting a
|
||||
// non-idempotent article: once submit may have started, recovery routes the task to 'unknown'
|
||||
// (manual reconcile) instead of auto-requeueing it. Best-effort — a stale/lost lease is a no-op
|
||||
// and must never block the in-flight publish.
|
||||
// (manual reconcile) instead of auto-requeueing it. The client must receive a
|
||||
// positive marker write before it performs the platform submit; a stale/lost
|
||||
// lease is rejected so the client can stop before the irreversible request.
|
||||
func (s *DesktopTaskService) MarkPublishSubmitStarted(ctx context.Context, client *repository.DesktopClient, taskID uuid.UUID, leaseToken string) error {
|
||||
if s == nil || s.pool == nil || client == nil {
|
||||
return nil
|
||||
@@ -732,7 +733,7 @@ func (s *DesktopTaskService) MarkPublishSubmitStarted(ctx context.Context, clien
|
||||
if leaseToken == "" {
|
||||
return response.ErrBadRequest(40001, "invalid_params", "lease_token is required")
|
||||
}
|
||||
if _, err := s.pool.Exec(ctx, `
|
||||
tag, err := s.pool.Exec(ctx, `
|
||||
UPDATE desktop_tasks
|
||||
SET publish_submit_started_at = COALESCE(publish_submit_started_at, NOW()),
|
||||
updated_at = NOW()
|
||||
@@ -741,9 +742,13 @@ func (s *DesktopTaskService) MarkPublishSubmitStarted(ctx context.Context, clien
|
||||
AND kind = 'publish'
|
||||
AND status = 'in_progress'
|
||||
AND lease_token_hash = $3
|
||||
`, taskID, client.ID, HashDesktopClientToken(leaseToken)); err != nil {
|
||||
`, taskID, client.ID, HashDesktopClientToken(leaseToken))
|
||||
if err != nil {
|
||||
return response.ErrInternal(50200, "desktop_task_submit_marker_failed", "failed to mark publish submit started")
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return response.ErrConflict(40983, "desktop_task_lease_invalid", "desktop task lease token is invalid or expired")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -558,17 +558,17 @@ func TestMeijiequanUpstreamThrottleSerializesRequests(t *testing.T) {
|
||||
redis := goredis.NewClient(&goredis.Options{Addr: server.Addr()})
|
||||
defer redis.Close()
|
||||
|
||||
client := NewMeijiequanClient(redis, config.MeijiequanConfig{UpstreamMinInterval: 25 * time.Millisecond})
|
||||
client := NewMeijiequanClient(redis, config.MeijiequanConfig{UpstreamMinInterval: 80 * time.Millisecond})
|
||||
ctx := context.Background()
|
||||
if err := client.waitForUpstreamTurn(ctx, 25*time.Millisecond); err != nil {
|
||||
if err := client.waitForUpstreamTurn(ctx, 80*time.Millisecond); err != nil {
|
||||
t.Fatalf("first wait failed: %v", err)
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
if err := client.waitForUpstreamTurn(ctx, 25*time.Millisecond); err != nil {
|
||||
if err := client.waitForUpstreamTurn(ctx, 80*time.Millisecond); err != nil {
|
||||
t.Fatalf("second wait failed: %v", err)
|
||||
}
|
||||
if elapsed := time.Since(start); elapsed < 20*time.Millisecond {
|
||||
if elapsed := time.Since(start); elapsed < 50*time.Millisecond {
|
||||
t.Fatalf("expected serialized upstream wait, elapsed %s", elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user