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))))))
|
(setq owner (etaf--semantic-component-identity semantic))))))
|
||||||
owner))
|
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)
|
(defun etaf--runtime-component-overlay (runtime)
|
||||||
"Publish RUNTIME dirty Component effects without traversing Root."
|
"Publish RUNTIME dirty Component effects without traversing Root."
|
||||||
(cl-block etaf--runtime-component-overlay
|
(cl-block etaf--runtime-component-overlay
|
||||||
@ -5749,6 +5759,9 @@ RENDERED-IDENTITIES names the Component render participants."
|
|||||||
backend-component-identities
|
backend-component-identities
|
||||||
journal resource-journal candidate-generation semantic-candidate
|
journal resource-journal candidate-generation semantic-candidate
|
||||||
participant)
|
participant)
|
||||||
|
(let ((evaluation-completed-p nil))
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
(etaf--runtime-begin-component-overlay runtime old)
|
(etaf--runtime-begin-component-overlay runtime old)
|
||||||
;; A source notification can race a generation promotion and leave an 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
|
;; effect id in the FIFO. Keep the dirty-id set and FIFO coherent before
|
||||||
@ -5844,6 +5857,10 @@ RENDERED-IDENTITIES names the Component render participants."
|
|||||||
(cl-pushnew effect-id
|
(cl-pushnew effect-id
|
||||||
(etaf-runtime-candidate-removed-effect-ids runtime)
|
(etaf-runtime-candidate-removed-effect-ids runtime)
|
||||||
:test #'eql))))
|
:test #'eql))))
|
||||||
|
(setq evaluation-completed-p t))
|
||||||
|
(unless evaluation-completed-p
|
||||||
|
(etaf--runtime-restore-component-overlay-retry
|
||||||
|
runtime retry-effect-ids))))
|
||||||
(setq range-changes
|
(setq range-changes
|
||||||
(append (nreverse
|
(append (nreverse
|
||||||
(etaf-runtime-candidate-eager-range-changes runtime))
|
(etaf-runtime-candidate-eager-range-changes runtime))
|
||||||
@ -6044,11 +6061,8 @@ RENDERED-IDENTITIES names the Component render participants."
|
|||||||
semantic-candidate))
|
semantic-candidate))
|
||||||
(etaf--runtime-rollback-prearm runtime journal)
|
(etaf--runtime-rollback-prearm runtime journal)
|
||||||
(etaf--runtime-rollback-resource-journal runtime resource-journal)
|
(etaf--runtime-rollback-resource-journal runtime resource-journal)
|
||||||
(etaf--runtime-clear-dirty-effects runtime)
|
(etaf--runtime-restore-component-overlay-retry
|
||||||
(dolist (effect-id retry-effect-ids)
|
runtime retry-effect-ids)
|
||||||
(etaf--runtime-enqueue-effect runtime effect-id))
|
|
||||||
(etaf--runtime-dispose-created-candidate runtime)
|
|
||||||
(etaf--runtime-clear-candidate runtime)
|
|
||||||
(signal (car err) (cdr err))))
|
(signal (car err) (cdr err))))
|
||||||
(etaf--runtime-participant-commit participant)
|
(etaf--runtime-participant-commit participant)
|
||||||
(etaf--runtime-complete-generation runtime candidate-generation)
|
(etaf--runtime-complete-generation runtime candidate-generation)
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
"ETAF scheduler projection test condition")
|
"ETAF scheduler projection test condition")
|
||||||
(define-error 'etaf-scheduler-test-body-condition
|
(define-error 'etaf-scheduler-test-body-condition
|
||||||
"ETAF scheduler body test 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)
|
(etaf-define-component etaf-scheduler-test-pair (&key left right)
|
||||||
"Render reactive LEFT and RIGHT values."
|
"Render reactive LEFT and RIGHT values."
|
||||||
@ -43,6 +45,16 @@
|
|||||||
(signal 'etaf-scheduler-test-projection-condition '("projection")))
|
(signal 'etaf-scheduler-test-projection-condition '("projection")))
|
||||||
(etaf-node 'text nil (list (symbol-name status)))))
|
(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)
|
(defun etaf-scheduler-test--text (buffer-name)
|
||||||
"Return BUFFER-NAME text without properties."
|
"Return BUFFER-NAME text without properties."
|
||||||
(with-current-buffer buffer-name
|
(with-current-buffer buffer-name
|
||||||
@ -494,6 +506,66 @@
|
|||||||
(etaf-value (etaf-data-error controller)))))
|
(etaf-value (etaf-data-error controller)))))
|
||||||
(etaf-data-stop 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 ()
|
(ert-deftest etaf-scheduler-detached-route-does-not-enter-fan-out ()
|
||||||
"An invalidated Runtime route cannot enqueue work in its old context."
|
"An invalidated Runtime route cannot enqueue work in its old context."
|
||||||
(let* ((buffer-name " *etaf-scheduler-stale-route*")
|
(let* ((buffer-name " *etaf-scheduler-stale-route*")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user