fix(runtime): restore overlay retry queue
This commit is contained in:
parent
aeb1b0f7c7
commit
4e75aaf0d3
@ -5734,6 +5734,16 @@ RENDERED-IDENTITIES names the Component render participants."
|
||||
(setq owner (etaf--semantic-component-identity semantic))))))
|
||||
owner))
|
||||
|
||||
(defun etaf--runtime-restore-component-overlay-retry
|
||||
(runtime retry-effect-ids)
|
||||
"Restore failed RUNTIME overlay work for RETRY-EFFECT-IDS."
|
||||
(etaf--runtime-clear-dirty-effects runtime)
|
||||
(dolist (effect-id retry-effect-ids)
|
||||
(etaf--runtime-enqueue-effect runtime effect-id))
|
||||
(etaf--runtime-dispose-created-candidate runtime)
|
||||
(etaf--runtime-rollback-behaviors runtime)
|
||||
(etaf--runtime-clear-candidate runtime))
|
||||
|
||||
(defun etaf--runtime-component-overlay (runtime)
|
||||
"Publish RUNTIME dirty Component effects without traversing Root."
|
||||
(cl-block etaf--runtime-component-overlay
|
||||
@ -5749,7 +5759,10 @@ RENDERED-IDENTITIES names the Component render participants."
|
||||
backend-component-identities
|
||||
journal resource-journal candidate-generation semantic-candidate
|
||||
participant)
|
||||
(etaf--runtime-begin-component-overlay runtime old)
|
||||
(let ((evaluation-completed-p nil))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(etaf--runtime-begin-component-overlay runtime old)
|
||||
;; A source notification can race a generation promotion and leave an old
|
||||
;; effect id in the FIFO. Keep the dirty-id set and FIFO coherent before
|
||||
;; sorting; stale ids are retired by the candidate generation cleanup.
|
||||
@ -5844,6 +5857,10 @@ RENDERED-IDENTITIES names the Component render participants."
|
||||
(cl-pushnew effect-id
|
||||
(etaf-runtime-candidate-removed-effect-ids runtime)
|
||||
:test #'eql))))
|
||||
(setq evaluation-completed-p t))
|
||||
(unless evaluation-completed-p
|
||||
(etaf--runtime-restore-component-overlay-retry
|
||||
runtime retry-effect-ids))))
|
||||
(setq range-changes
|
||||
(append (nreverse
|
||||
(etaf-runtime-candidate-eager-range-changes runtime))
|
||||
@ -6044,11 +6061,8 @@ RENDERED-IDENTITIES names the Component render participants."
|
||||
semantic-candidate))
|
||||
(etaf--runtime-rollback-prearm runtime journal)
|
||||
(etaf--runtime-rollback-resource-journal runtime resource-journal)
|
||||
(etaf--runtime-clear-dirty-effects runtime)
|
||||
(dolist (effect-id retry-effect-ids)
|
||||
(etaf--runtime-enqueue-effect runtime effect-id))
|
||||
(etaf--runtime-dispose-created-candidate runtime)
|
||||
(etaf--runtime-clear-candidate runtime)
|
||||
(etaf--runtime-restore-component-overlay-retry
|
||||
runtime retry-effect-ids)
|
||||
(signal (car err) (cdr err))))
|
||||
(etaf--runtime-participant-commit participant)
|
||||
(etaf--runtime-complete-generation runtime candidate-generation)
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
"ETAF scheduler projection test condition")
|
||||
(define-error 'etaf-scheduler-test-body-condition
|
||||
"ETAF scheduler body test condition")
|
||||
(define-error 'etaf-scheduler-test-render-recovery-condition
|
||||
"ETAF scheduler render recovery condition")
|
||||
|
||||
(etaf-define-component etaf-scheduler-test-pair (&key left right)
|
||||
"Render reactive LEFT and RIGHT values."
|
||||
@ -43,6 +45,16 @@
|
||||
(signal 'etaf-scheduler-test-projection-condition '("projection")))
|
||||
(etaf-node 'text nil (list (symbol-name status)))))
|
||||
|
||||
(etaf-define-component etaf-scheduler-test-render-recovery
|
||||
(&key source fail)
|
||||
"Render SOURCE unless FAIL requests a deterministic render error."
|
||||
:render
|
||||
(progn
|
||||
(when (etaf-value fail)
|
||||
(signal 'etaf-scheduler-test-render-recovery-condition
|
||||
'("expected render failure" :payload recovery)))
|
||||
(etaf-node 'text nil (list (format "Value %s" (etaf-value source))))))
|
||||
|
||||
(defun etaf-scheduler-test--text (buffer-name)
|
||||
"Return BUFFER-NAME text without properties."
|
||||
(with-current-buffer buffer-name
|
||||
@ -494,6 +506,66 @@
|
||||
(etaf-value (etaf-data-error controller)))))
|
||||
(etaf-data-stop controller))))
|
||||
|
||||
(ert-deftest etaf-scheduler-render-failure-keeps-retry-fifo-coherent ()
|
||||
"A failed Component evaluation retries and visibly recovers on new state."
|
||||
(let* ((buffer-name " *etaf-scheduler-render-recovery*")
|
||||
(source (etaf-ref "A"))
|
||||
(fail (etaf-ref nil))
|
||||
captured)
|
||||
(unwind-protect
|
||||
(progn
|
||||
(etaf-mount
|
||||
buffer-name
|
||||
(etaf--view-call
|
||||
'etaf-scheduler-test-render-recovery
|
||||
(list :source source :fail fail) nil))
|
||||
(setf (etaf-value source) "B")
|
||||
(let* ((runtime (etaf-runtime-for-buffer buffer-name))
|
||||
(generation (etaf-runtime-generation runtime))
|
||||
(revision
|
||||
(plist-get (ebox-buffer-update-report buffer-name)
|
||||
:surface-revision))
|
||||
(contents
|
||||
(with-current-buffer buffer-name (buffer-string))))
|
||||
(condition-case condition
|
||||
(setf (etaf-value fail) t)
|
||||
(etaf-scheduler-test-render-recovery-condition
|
||||
(setq captured condition)))
|
||||
(should
|
||||
(equal captured
|
||||
'(etaf-scheduler-test-render-recovery-condition
|
||||
"expected render failure" :payload recovery)))
|
||||
(should (= generation (etaf-runtime-generation runtime)))
|
||||
(should (= revision
|
||||
(plist-get (ebox-buffer-update-report buffer-name)
|
||||
:surface-revision)))
|
||||
(should (equal-including-properties
|
||||
contents (with-current-buffer buffer-name
|
||||
(buffer-string))))
|
||||
(should
|
||||
(equal (sort (hash-table-keys
|
||||
(etaf-runtime-dirty-effect-ids runtime)) #'<)
|
||||
(sort (copy-sequence
|
||||
(etaf-runtime-dirty-effect-queue runtime)) #'<)))
|
||||
(etaf-reactive-call-with-batch
|
||||
(lambda ()
|
||||
(setf (etaf-value fail) nil)
|
||||
(setf (etaf-value source) "C")))
|
||||
(should (equal "Value C"
|
||||
(etaf-scheduler-test--text buffer-name)))
|
||||
(should (= (1+ generation)
|
||||
(etaf-runtime-generation runtime)))
|
||||
(should (= (1+ revision)
|
||||
(plist-get (ebox-buffer-update-report buffer-name)
|
||||
:surface-revision)))
|
||||
(should-not (hash-table-keys
|
||||
(etaf-runtime-dirty-effect-ids runtime)))
|
||||
(should-not (etaf-runtime-dirty-effect-queue runtime))))
|
||||
(when-let* ((runtime (etaf-runtime-for-buffer buffer-name)))
|
||||
(etaf-unmount runtime))
|
||||
(when-let* ((buffer (get-buffer buffer-name)))
|
||||
(kill-buffer buffer)))))
|
||||
|
||||
(ert-deftest etaf-scheduler-detached-route-does-not-enter-fan-out ()
|
||||
"An invalidated Runtime route cannot enqueue work in its old context."
|
||||
(let* ((buffer-name " *etaf-scheduler-stale-route*")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user