[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/hyperdrive 063c2275d1 09/49: WIP: (-fill-version-ranges) F
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/hyperdrive 063c2275d1 09/49: WIP: (-fill-version-ranges) Fill existent and nonexistent ranges |
Date: |
Wed, 20 Sep 2023 19:01:32 -0400 (EDT) |
branch: elpa/hyperdrive
commit 063c2275d151a086ebf248f50288bd46a49367f9
Author: Joseph Turner <joseph@ushin.org>
Commit: Joseph Turner <joseph@ushin.org>
WIP: (-fill-version-ranges) Fill existent and nonexistent ranges
Two codepaths:
- fill existent entries in series
- fill nonexistent entries in parallel
Filling existent entries is logically recursive: fill entry, get its
range-start, then fill the entry at the range-end of the prior range.
Filling nonexistent entries is not recursive: In parallel, send
a request to every version of entry between
(hyperdrive-entry-version entry)
and
(- (hyperdrive-entry-version entry) hyperdrive-queue-size)
If the earliest requested version is existent, go back to the
"existent series" codepath. Otherwise, repeat the "nonexistent
parallel" codepath.
So good, so far.
The problem is that the finally callback passed to
`hyperdrive-fill-version-ranges' is not called in the correct place.
We check the earliest requested version at the end of the "nonexistent
parallel" codepath inside a separate queue finalizer for the codepath.
Since the "nonexistent parallel" async requests are not made in the
main queue used by "existent series" codepath, the main queue runs
whenever the "existent series" codepath hands control over to the
"nonexistent parallel" codepath.
What about multiple queues per request, each with its own finalizer?
---
hyperdrive-history.el | 1 +
hyperdrive-lib.el | 89 +++++++++++++++++++++++++++++++++++----------------
2 files changed, 63 insertions(+), 27 deletions(-)
diff --git a/hyperdrive-history.el b/hyperdrive-history.el
index 8ed090f8fd..b0fc207ca6 100644
--- a/hyperdrive-history.el
+++ b/hyperdrive-history.el
@@ -227,6 +227,7 @@ Universal prefix argument \\[universal-argument] forces
(setf (hyperdrive-entry-version range-end-entry) range-end)
(hyperdrive-fill-version-ranges range-end-entry
:finally (lambda ()
+ (message "FINALLY")
;; TODO: Should we open the history buffer for entry
;; or range-end-entry or...?
(hyperdrive-history entry)))))
diff --git a/hyperdrive-lib.el b/hyperdrive-lib.el
index faceaa7987..ecfc92201d 100644
--- a/hyperdrive-lib.el
+++ b/hyperdrive-lib.el
@@ -813,33 +813,68 @@ The QUEUE argument is used in recursive calls."
(unless queue
(setf queue (make-plz-queue :limit hyperdrive-queue-size
:finally (when finally finally))))
- (let ((copy-entry (hyperdrive-copy-tree entry t)))
- (hyperdrive-fill copy-entry
- :then (lambda (filled-entry)
- (when (cl-plusp limit)
- ;; Don't use `hyperdrive-entry-previous' here, since it makes
a sync request
- (pcase-let ((`(,range-start . ,_plist)
(hyperdrive-entry-version-range filled-entry)))
- (setf (hyperdrive-entry-version filled-entry) (1-
range-start))
- (when (eq 'unknown (hyperdrive-entry-exists-p filled-entry))
- ;; Recurse backward through history, filling unknown
entries.
- ;; Stop recursing at known nonexistent entry or at the
limit.
- (hyperdrive-fill-version-ranges filled-entry
- :limit (1- limit) :queue queue)))))
- :else (lambda (err)
- (pcase (plz-response-status (plz-error-response err))
- ;; FIXME: If plz-error is a curl-error, this block will fail.
- (404
- ;; ENTRY is known nonexistent: send LIMIT number of
- ;; parallel requests for entries before ENTRY's version.
- (cl-dotimes (i limit)
- (cl-decf (hyperdrive-entry-version copy-entry))
- (unless (and (cl-plusp (hyperdrive-entry-version
copy-entry))
- (eq 'unknown (hyperdrive-entry-exists-p
copy-entry)))
- (cl-return))
- (hyperdrive-fill-version-ranges copy-entry
- :limit 0 :queue queue)))
- (_ (signal (car err) (cdr err)))))
- :queue queue)))
+ (cl-labels ((fill-existent (entry limit)
+ ;; For existent entries, send requests in series.
+ (when (cl-plusp limit)
+ ;; Don't use `hyperdrive-entry-previous' here, since it
makes a sync request
+ (pcase-let ((`(,range-start . ,_plist)
(hyperdrive-entry-version-range entry)))
+ (setf (hyperdrive-entry-version entry) (1- range-start))
+ (when (eq 'unknown (hyperdrive-entry-exists-p entry))
+ ;; Recurse backward through history.
+ (hyperdrive-fill-version-ranges entry
+ :limit (1- limit) :queue queue)))))
+ (fill-nonexistent (copy-entry limit)
+ (let ((nonexistent-queue (make-plz-queue
+ :limit hyperdrive-queue-size
+ :finally (lambda ()
+ (let ((new-limit (- limit
hyperdrive-queue-size))
+
(last-requested-entry (hyperdrive-copy-tree entry t)))
+ (cl-incf
(hyperdrive-entry-version last-requested-entry))
+ ;; (message "ENTRY2: %s
%s" (hyperdrive-entry-version entry) (hyperdrive-entry-exists-p
last-requested-entry))
+ (if
(hyperdrive-entry-exists-p last-requested-entry)
+ (fill-existent
entry new-limit)
+ (fill-nonexistent
entry new-limit)))))))
+ ;; For nonexistent entries, send requests in parallel.
+ (cl-dotimes (i hyperdrive-queue-size)
+ ;; Send the maximum number of simultaneous requests.
+ (cl-decf (hyperdrive-entry-version entry))
+ ;; (message "ENTRY0: %s %s %s %s"
(hyperdrive-entry-version entry) (hyperdrive-entry-exists-p entry) limit i)
+ (unless (and (cl-plusp (hyperdrive-entry-version entry))
+ (eq 'unknown (hyperdrive-entry-exists-p
entry))
+ (> limit i))
+ ;; Stop at the beginning of the history, at a known
+ ;; existent/nonexistent entry, or at the limit.
+ (cl-return))
+ ;; (message "ENTRY1: %s %s" (hyperdrive-entry-version
entry) (hyperdrive-entry-exists-p entry))
+
+ (hyperdrive-fill (hyperdrive-copy-tree entry t)
+ ;; `hyperdrive-fill' is only used to fill the version
ranges;
+ ;; the filled-entry is thrown away.
+ :then (lambda (_filled-entry)
+ ;; (message "KNOWN-EXISTENT: %s"
(hyperdrive-entry-version filled-entry))
+ (message "THEN")
+ )
+ :else (lambda (err)
+ (message "KNOWN-NONEXISTENT: %s"
(hyperdrive-entry-version entry))
+ ;; TODO: Better error handling.
+ (pcase (plz-response-status (plz-error-response
err))
+ ;; FIXME: If plz-error is a curl-error, this
block will fail.
+ (404 nil)
+ (_ (signal (car err) (cdr err)))))
+ :queue nonexistent-queue)))))
+ (let ((copy-entry (hyperdrive-copy-tree entry t)))
+ (hyperdrive-fill copy-entry
+ ;; `hyperdrive-fill' is only used to fill the version ranges;
+ ;; the filled-entry is thrown away.
+ :then (lambda (_filled-entry)
+ (fill-existent copy-entry limit))
+ :else (lambda (err)
+ (pcase (plz-response-status (plz-error-response err))
+ ;; FIXME: If plz-error is a curl-error, this block will fail.
+ (404
+ (fill-nonexistent copy-entry limit))
+ (_ (signal (car err) (cdr err)))))
+ :queue queue))))
(defun hyperdrive-fill-metadata (hyperdrive)
"Fill HYPERDRIVE's public metadata and return it.
- [nongnu] elpa/hyperdrive 395d1dd5e0 25/49: Fix: (-fill-version-ranges) Stop filling when loop returns early, (continued)
- [nongnu] elpa/hyperdrive 395d1dd5e0 25/49: Fix: (-fill-version-ranges) Stop filling when loop returns early, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 8dc8f09a82 30/49: Comment: Add TODO, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 77186465d7 33/49: WIP: Fixes, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 1844b57f51 39/49: Fix: (-update-nonexistent-version-range) Add default finally, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 44413406c9 40/49: Change: (-history-fill-version-ranges) Add loading indicator, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive e2ddaa770c 01/49: Change: (hyperdrive-fill-version-ranges) Only recurse from ENTRY, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 509f72b4f0 02/49: Change: (hyperdrive-history) Display history buffer immediately, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive d93ab84313 06/49: Meta: Update changelog, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 32580aaa6c 07/49: Docs: Document hyperdrive-fill-version-ranges-limit, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive f2474f65f0 08/49: Change: (-fill-version-ranges) In ELSE, send parallel requests, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 063c2275d1 09/49: WIP: (-fill-version-ranges) Fill existent and nonexistent ranges,
ELPA Syncer <=
- [nongnu] elpa/hyperdrive 73cef39917 12/49: WIP: Fix off-by-one, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 05a0421bbb 16/49: Change: (hyperdrive-fill-version-ranges) Use finishedp flag, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive cb91f4adac 03/49: Add: (-history-fill-version-ranges) Interactively fill versions, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 2c8a76234d 20/49: Tidy: (-fill-version-ranges) Rename queue to fill-entry-queue, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 830904c5cf 22/49: Comment: Remove TODO, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 92a54cb93c 23/49: Fix: (hyperdrive-update-nonexistent-version-range) Docstring, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 53b48e337e 27/49: Tidy: (hyperdrive-fill-version-ranges) Don't let-bind finally, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 46490c55a2 26/49: Tidy: (-fill-version-ranges) Return nil from cl-dotimes for clarity, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive 758486bcdd 28/49: Change: Rename hyperdrive-queue-size to hyperdrive-queue-limit, ELPA Syncer, 2023/09/20
- [nongnu] elpa/hyperdrive a61c660ee6 29/49: Change: (-fill-version-ranges) Rename limit to total-requests-limit, ELPA Syncer, 2023/09/20