[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/plz-media-type 4488497d71 09/26: Run handler code via a
From: |
ELPA Syncer |
Subject: |
[elpa] externals/plz-media-type 4488497d71 09/26: Run handler code via a timer in the main loop |
Date: |
Wed, 1 May 2024 09:59:00 -0400 (EDT) |
branch: externals/plz-media-type
commit 4488497d71cb041f7949f4b87e926f4422f128a6
Author: Roman Scherer <roman@burningswell.com>
Commit: Roman Scherer <roman@burningswell.com>
Run handler code via a timer in the main loop
---
plz-media-type.el | 88 ++++++++++++++++++++------------------------
tests/test-plz-media-type.el | 40 --------------------
2 files changed, 40 insertions(+), 88 deletions(-)
diff --git a/plz-media-type.el b/plz-media-type.el
index 7927561adc..768e77fc75 100644
--- a/plz-media-type.el
+++ b/plz-media-type.el
@@ -44,13 +44,6 @@
(require 'eieio)
(require 'plz)
-(define-error 'plz-media-type-filter-error
- "plz-media-type: Error in process filter"
- 'plz-error)
-
-(cl-defstruct (plz-media-type-filter-error (:include plz-error))
- cause)
-
(defclass plz-media-type ()
((coding-system
:documentation "The coding system to use for the media type."
@@ -166,6 +159,18 @@ an alist of parameters."
(defvar-local plz-media-type--response nil
"The response of the process buffer.")
+(defun plz-media-type--schedule (handler messages)
+ "Schedule MESSAGES to be processed with the HANDLER on a timer."
+ (cl-loop with time = (current-time)
+ for msg = (pop messages) while msg
+ do (let ((timer (timer-create)))
+ (timer-set-time timer time)
+ (timer-set-function timer
+ (lambda (handler msg)
+ (with-temp-buffer (funcall handler msg)))
+ (list handler msg))
+ (timer-activate timer))))
+
(defun plz-media-type--parse-headers ()
"Parse the HTTP response headers in the current buffer."
(forward-line 1)
@@ -360,24 +365,25 @@ will always be set to nil.")
(defun plz-media-type:application/json-array--parse-stream (media-type)
"Parse all lines of the newline delimited JSON MEDIA-TYPE in the PROCESS
buffer."
- (with-slots (handler) media-type
+ (let ((objects))
(unless plz-media-type--position
(setq-local plz-media-type--position (point)))
(goto-char plz-media-type--position)
(when-let (result (plz-media-type:application/json-array--consume-next
media-type))
(while result
- (when (and (equal :array-element (car result))
- (functionp handler))
- (funcall handler (cdr result)))
- (setq result (plz-media-type:application/json-array--consume-next
media-type))))))
+ (when (equal :array-element (car result))
+ (push (cdr result) objects))
+ (setq result (plz-media-type:application/json-array--consume-next
media-type))))
+ objects))
(cl-defmethod plz-media-type-process
((media-type plz-media-type:application/json-array) process chunk)
"Process the CHUNK according to MEDIA-TYPE using PROCESS."
- (ignore media-type)
(cl-call-next-method media-type process chunk)
- (plz-media-type:application/json-array--parse-stream media-type)
- (set-marker (process-mark process) (point-max)))
+ (with-slots (handler) media-type
+ (let ((objects (plz-media-type:application/json-array--parse-stream
media-type)))
+ (set-marker (process-mark process) (point-max))
+ (plz-media-type--schedule handler objects))))
(cl-defmethod plz-media-type-then
((media-type plz-media-type:application/json-array) response)
@@ -417,21 +423,24 @@ will always be set to nil.")
(defun plz-media-type:application/x-ndjson--parse-stream (media-type)
"Parse all lines of the newline delimited JSON MEDIA-TYPE in the PROCESS
buffer."
(with-slots (handler) media-type
- (unless plz-media-type--position
- (setq-local plz-media-type--position (point)))
- (goto-char plz-media-type--position)
- (when-let (object (plz-media-type:application/x-ndjson--parse-line
media-type))
- (while object
- (setq-local plz-media-type--position (point))
- (when (functionp handler)
- (funcall handler object))
- (setq object (plz-media-type:application/x-ndjson--parse-line
media-type))))))
+ (let (objects)
+ (unless plz-media-type--position
+ (setq-local plz-media-type--position (point)))
+ (goto-char plz-media-type--position)
+ (when-let (object (plz-media-type:application/x-ndjson--parse-line
media-type))
+ (while object
+ (setq-local plz-media-type--position (point))
+ (push object objects)
+ (setq object (plz-media-type:application/x-ndjson--parse-line
media-type))))
+ objects)))
(cl-defmethod plz-media-type-process
((media-type plz-media-type:application/x-ndjson) process chunk)
"Process the CHUNK according to MEDIA-TYPE using PROCESS."
(cl-call-next-method media-type process chunk)
- (plz-media-type:application/x-ndjson--parse-stream media-type))
+ (with-slots (handler) media-type
+ (let ((objects (plz-media-type:application/x-ndjson--parse-stream
media-type)))
+ (plz-media-type--schedule handler objects))))
(cl-defmethod plz-media-type-then
((media-type plz-media-type:application/x-ndjson) response)
@@ -511,11 +520,6 @@ parsing the HTTP response body with the
(defun plz-media-type--handle-sync-error (error media-types)
"Handle the synchronous ERROR using MEDIA-TYPES."
(cond
- ((plz-media-type-filter-error-p error)
- (signal 'plz-media-type-filter-error
- (list (plz-media-type-filter-error-message error)
- (plz-media-type-filter-error-response error)
- (plz-media-type-filter-error-cause error))))
((eq 'plz-http-error (car error))
(plz-media-type--handle-sync-http-error error media-types))
(t (signal (car error) (cdr error)))))
@@ -637,7 +641,7 @@ not.
(if-let (media-types (pcase as
(`(media-types ,media-types)
media-types)))
- (let ((buffer) (filter-error))
+ (let ((buffer))
(condition-case error
(let* ((plz-curl-default-args (cons "--no-buffer"
plz-curl-default-args))
(result (plz method url
@@ -649,10 +653,9 @@ not.
:else (lambda (error)
(setq buffer (current-buffer))
(when (or (functionp else) (symbolp else))
- (funcall else (or filter-error
- (plz-media-type-else
-
plz-media-type--current
- error)))))
+ (funcall else (plz-media-type-else
+ plz-media-type--current
+ error))))
:finally (lambda ()
(unwind-protect
(when (functionp finally)
@@ -662,18 +665,7 @@ not.
:headers headers
:noquery noquery
:filter (lambda (process chunk)
- (condition-case cause
- (plz-media-type-process-filter
process media-types chunk)
- (error
- (let ((buffer (process-buffer
process)))
- (setq filter-error
-
(make-plz-media-type-filter-error
- :cause cause
- :message (format "error in
process filter: %S" cause)
- :response (when
(buffer-live-p buffer)
-
(with-current-buffer buffer
-
plz-media-type--response))))
- (delete-process process)))))
+ (plz-media-type-process-filter process
media-types chunk))
:timeout timeout
:then (if (symbolp then)
then
@@ -694,7 +686,7 @@ not.
(t (user-error "Unexpected response: %s" result))))
;; TODO: How to kill the buffer for sync requests that raise an
error?
(plz-error
- (plz-media-type--handle-sync-error (or filter-error error)
media-types))))
+ (plz-media-type--handle-sync-error error media-types))))
(apply #'plz (append (list method url) rest))))
;;;; Footer
diff --git a/tests/test-plz-media-type.el b/tests/test-plz-media-type.el
index 3204f6e9ac..185e04e33c 100644
--- a/tests/test-plz-media-type.el
+++ b/tests/test-plz-media-type.el
@@ -146,46 +146,6 @@
(let ((media-type (plz-media-type-parse "text/html")))
(should (equal 'text/html (plz-media-type-symbol media-type)))))
-(ert-deftest test-plz-media-type-process-filter-error-sync ()
- (plz-media-type-test-with-mock-response (plz-media-type-test-response
"application/x-ndjson/ollama-hello.txt")
- (let ((result (condition-case error
- (plz-media-type-request 'get "MOCK-URL"
- :as `(media-types ((application/x-ndjson
- .
,(plz-media-type:application/x-ndjson
- :handler (lambda (_) (signal
'error "boom")))))))
- (plz-error error))))
- (should (equal 'plz-media-type-filter-error (elt result 0)))
- (should (equal "error in process filter: (error . \"boom\")" (elt result
1)))
- (let ((response (elt result 2)))
- (should (plz-response-p response))
- (should (equal 200 (plz-response-status response)))
- (should (null (plz-response-body response))))
- (should (equal '(error . "boom") (elt result 3))))))
-
-(ert-deftest test-plz-media-type-process-filter-error-async ()
- (plz-media-type-test-with-mock-response (plz-media-type-test-response
"application/x-ndjson/ollama-hello.txt")
- (let* ((else) (finally) (then)
- (process (plz-media-type-request 'get "MOCK-URL"
- :as `(media-types ((application/x-ndjson
- .
,(plz-media-type:application/x-ndjson
- :handler (lambda (_) (signal
'error "boom"))))))
- :else (lambda (object) (push object else))
- :finally (lambda () (push t finally))
- :then (lambda (object) (push object then)))))
- (plz-media-type-test-wait process)
- (should (equal '(t) finally))
- (should (equal 0 (length then)))
- (should (equal 1 (length else)))
- (seq-doseq (error else)
- (should (plz-error-p error))
- (should (plz-media-type-filter-error-p error))
- (should (equal "error in process filter: (error . \"boom\")"
(plz-error-message error)))
- (should (equal '(error . "boom") (plz-media-type-filter-error-cause
error)))
- (let ((response (plz-error-response error)))
- (should (plz-response-p response))
- (should (equal 200 (plz-response-status response)))
- (should (null (plz-response-body response))))))))
-
(ert-deftest test-plz-media-type-request:application/octet-stream:stream ()
(plz-media-type-test-with-mock-response (plz-media-type-test-response
"text/event-stream/openai-hello.txt")
(let* ((else) (finally) (then)
- [elpa] externals/plz-media-type 3361c5df22 21/26: Add vendor note, (continued)
- [elpa] externals/plz-media-type 3361c5df22 21/26: Add vendor note, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 6e820a3a0c 11/26: Remove obsolete section about plz-media-type-filter-error, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type c97da04f3a 20/26: Make plz-media-type-of-response public, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 88c163d1de 05/26: Align test names, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type b81f878302 03/26: Remove calls to parse the stream from the then callbacks, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 7bba4e846d 01/26: Initial commit, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 431050411e 07/26: Rename :process-filter option to :filter, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 06910752fa 26/26: Split manual and README, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 201963531c 16/26: Rename plz-media-type-decode-string to plz-media-type-decode-coding-string, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 12f3ab1477 12/26: Make plz-media-type--parse private, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 4488497d71 09/26: Run handler code via a timer in the main loop,
ELPA Syncer <=
- [elpa] externals/plz-media-type 8c0d9e14fa 25/26: ELPA preparations, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 18109a6034 04/26: Add sync/async tests for application/x-ndjson, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type ff3f01eb60 19/26: Fix typo, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 6192587659 22/26: Tweak vendor note, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 218c98099f 17/26: Rename function to plz-media-type-decode-coding-string, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 6c9cca634d 08/26: Parse response without widen, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type d7b1f616c4 18/26: Run tests on Emacs 29.3 as well, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type 0ddb38a356 13/26: Make plz-media-type-of-response private, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type c2c7f5f2ef 02/26: Add tests for DNS resolve errors, ELPA Syncer, 2024/05/01
- [elpa] externals/plz-media-type ecd8628118 23/26: Depend on plz v0.8, ELPA Syncer, 2024/05/01