aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/url/url-queue.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/url/url-queue.el')
-rw-r--r--lisp/url/url-queue.el61
1 files changed, 53 insertions, 8 deletions
diff --git a/lisp/url/url-queue.el b/lisp/url/url-queue.el
index 534c94b4d52..9dfee485918 100644
--- a/lisp/url/url-queue.el
+++ b/lisp/url/url-queue.el
@@ -30,6 +30,7 @@
30 30
31(eval-when-compile (require 'cl)) 31(eval-when-compile (require 'cl))
32(require 'browse-url) 32(require 'browse-url)
33(require 'url-parse)
33 34
34(defcustom url-queue-parallel-processes 6 35(defcustom url-queue-parallel-processes 6
35 "The number of concurrent processes." 36 "The number of concurrent processes."
@@ -49,21 +50,47 @@
49 50
50(defstruct url-queue 51(defstruct url-queue
51 url callback cbargs silentp 52 url callback cbargs silentp
52 buffer start-time) 53 buffer start-time pre-triggered
54 inhibit-cookiesp)
53 55
54;;;###autoload 56;;;###autoload
55(defun url-queue-retrieve (url callback &optional cbargs silent) 57(defun url-queue-retrieve (url callback &optional cbargs silent inhibit-cookies)
56 "Retrieve URL asynchronously and call CALLBACK with CBARGS when finished. 58 "Retrieve URL asynchronously and call CALLBACK with CBARGS when finished.
57Like `url-retrieve' (which see for details of the arguments), but 59This is like `url-retrieve' (which see for details of the arguments),
58controls the level of parallelism via the 60but with limits on the degree of parallelism. The variable
59`url-queue-parallel-processes' variable." 61`url-queue-parallel-processes' sets the number of concurrent processes.
62The variable `url-queue-timeout' sets a timeout."
60 (setq url-queue 63 (setq url-queue
61 (append url-queue 64 (append url-queue
62 (list (make-url-queue :url url 65 (list (make-url-queue :url url
63 :callback callback 66 :callback callback
64 :cbargs cbargs 67 :cbargs cbargs
65 :silentp silent)))) 68 :silentp silent
66 (url-queue-run-queue)) 69 :inhibit-cookiesp inhibit-cookies))))
70 (url-queue-setup-runners))
71
72;; To ensure asynch behaviour, we start the required number of queue
73;; runners from `run-with-idle-timer'. So we're basically going
74;; through the queue in two ways: 1) synchronously when a program
75;; calls `url-queue-retrieve' (which will then start the required
76;; number of queue runners), and 2) at the exit of each job, which
77;; will then not start any further threads, but just reuse the
78;; previous "slot".
79
80(defun url-queue-setup-runners ()
81 (let ((running 0)
82 waiting)
83 (dolist (entry url-queue)
84 (cond
85 ((or (url-queue-start-time entry)
86 (url-queue-pre-triggered entry))
87 (incf running))
88 ((not waiting)
89 (setq waiting entry))))
90 (when (and waiting
91 (< running url-queue-parallel-processes))
92 (setf (url-queue-pre-triggered waiting) t)
93 (run-with-idle-timer 0.01 nil 'url-queue-run-queue))))
67 94
68(defun url-queue-run-queue () 95(defun url-queue-run-queue ()
69 (url-queue-prune-old-entries) 96 (url-queue-prune-old-entries)
@@ -81,16 +108,34 @@ controls the level of parallelism via the
81 (url-queue-start-retrieve waiting)))) 108 (url-queue-start-retrieve waiting))))
82 109
83(defun url-queue-callback-function (status job) 110(defun url-queue-callback-function (status job)
111 (when (and (eq (car status) :error)
112 (eq (cadr (cadr status)) 'connection-failed))
113 ;; If we get a connection error, then flush all other jobs from
114 ;; the host from the queue. This particularly makes sense if the
115 ;; error really is a DNS resolver issue, which happens
116 ;; synchronously and totally halts Emacs.
117 (url-queue-remove-jobs-from-host
118 (plist-get (nthcdr 3 (cadr status)) :host)))
84 (setq url-queue (delq job url-queue)) 119 (setq url-queue (delq job url-queue))
85 (url-queue-run-queue) 120 (url-queue-run-queue)
86 (apply (url-queue-callback job) (cons status (url-queue-cbargs job)))) 121 (apply (url-queue-callback job) (cons status (url-queue-cbargs job))))
87 122
123(defun url-queue-remove-jobs-from-host (host)
124 (let ((jobs nil))
125 (dolist (job url-queue)
126 (when (equal (url-host (url-generic-parse-url (url-queue-url job)))
127 host)
128 (push job jobs)))
129 (dolist (job jobs)
130 (setq url-queue (delq job url-queue)))))
131
88(defun url-queue-start-retrieve (job) 132(defun url-queue-start-retrieve (job)
89 (setf (url-queue-buffer job) 133 (setf (url-queue-buffer job)
90 (ignore-errors 134 (ignore-errors
91 (url-retrieve (url-queue-url job) 135 (url-retrieve (url-queue-url job)
92 #'url-queue-callback-function (list job) 136 #'url-queue-callback-function (list job)
93 (url-queue-silentp job))))) 137 (url-queue-silentp job)
138 (url-queue-inhibit-cookiesp job)))))
94 139
95(defun url-queue-prune-old-entries () 140(defun url-queue-prune-old-entries ()
96 (let (dead-jobs) 141 (let (dead-jobs)