Function: jsonrpc-request
jsonrpc-request is a byte-compiled function defined in jsonrpc.el.gz.
Signature
(jsonrpc-request CONNECTION METHOD PARAMS &rest ARGS &key DEFERRED TIMEOUT CANCEL-ON-QUIT CANCEL-ON-INPUT CANCEL-ON-INPUT-RETVAL)
Documentation
Make a request to CONNECTION, synchronously wait for a reply.
CONNECTION, METHOD, PARAMS, DEFERRED and TIMEOUT are interpreted as in
jsonrpc-async-request, which see.
This function has two exit modes: local and non-local. Except for
CANCEL-ON-INPUT, explained below, the only normal local exit occurs when
the remote endpoint succeeds, in which case a JSONRPC result object is
returned. A remote endpoint error or a local timeout cause a non-local
exit with a jsonrpc-error condition.
A user quit (C-g'/keyboard-quit) causes a non-local exit with a
quit condition. A non-nil CANCEL-ON-QUIT must be a function of a
single argument, ID, which identifies the request as specified in the
JSONRPC 2.0 spec. Callers may use this function to issue a cancel
notification to the endpoint, thus preventing it from continuing to work
on the request.
If CANCEL-ON-INPUT is non-nil and any type of user input is detected
while waiting for a response jsonrpc-request locally exits
immediately, returning CANCEL-ON-INPUT-RETVAL. CANCEL-ON-INPUT can also
be a function with the same semantics as CANCEL-ON-QUIT. Since the a
C-g/keyboard-quit also counts as user input, CANCEL-ON-INPUT
nullifies the effect of CANCEL-ON-QUIT.
On either cancellation scenario, any future remote endpoint replies to the original request (normal or error) are ignored.
Source Code
;; Defined in /usr/src/emacs/lisp/jsonrpc.el.gz
(cl-defun jsonrpc-request (connection
method params
&rest args
&key
deferred timeout
cancel-on-quit
cancel-on-input
cancel-on-input-retval)
"Make a request to CONNECTION, synchronously wait for a reply.
CONNECTION, METHOD, PARAMS, DEFERRED and TIMEOUT are interpreted as in
`jsonrpc-async-request', which see.
This function has two exit modes: local and non-local. Except for
CANCEL-ON-INPUT, explained below, the only normal local exit occurs when
the remote endpoint succeeds, in which case a JSONRPC result object is
returned. A remote endpoint error or a local timeout cause a non-local
exit with a `jsonrpc-error' condition.
A user quit (`'C-g'/`keyboard-quit') causes a non-local exit with a
`quit' condition. A non-nil CANCEL-ON-QUIT must be a function of a
single argument, ID, which identifies the request as specified in the
JSONRPC 2.0 spec. Callers may use this function to issue a cancel
notification to the endpoint, thus preventing it from continuing to work
on the request.
If CANCEL-ON-INPUT is non-nil and any type of user input is detected
while waiting for a response `jsonrpc-request' locally exits
immediately, returning CANCEL-ON-INPUT-RETVAL. CANCEL-ON-INPUT can also
be a function with the same semantics as CANCEL-ON-QUIT. Since the a
`C-g'/`keyboard-quit' also counts as user input, CANCEL-ON-INPUT
nullifies the effect of CANCEL-ON-QUIT.
On either cancellation scenario, any future remote endpoint replies
to the original request (normal or error) are ignored."
(let* ((tag (funcall (if (fboundp 'gensym) 'gensym 'cl-gensym)
"jsonrpc-request-catch-tag"))
id-and-timer
canceled
(throw-on-input nil)
retval)
(unwind-protect
(catch tag
(setq
id-and-timer
(apply
#'jsonrpc--async-request-1
connection method params
:sync-request t
:success-fn (lambda (result)
(unless canceled
(setq retval `(done ,result))
(throw tag nil)))
:error-fn
(jsonrpc-lambda
(&key code message data)
(unless canceled
(setq retval `(error (jsonrpc-error-code . ,code)
(jsonrpc-error-message . ,message)
(jsonrpc-error-data . ,data)))
(throw tag nil)))
:timeout-fn
(lambda ()
(unless canceled
(setq retval '(error (jsonrpc-error-message . "Timed out")))
(throw tag nil)))
`(,@(when (plist-member args :deferred) `(:deferred ,deferred))
,@(when (plist-member args :timeout) `(:timeout ,timeout)))))
(cond (cancel-on-input
(unwind-protect
(let ((inhibit-quit t) (inhibit-redisplay t))
(while (sit-for 30 t)))
(setq canceled t))
(when (functionp cancel-on-input)
(funcall cancel-on-input (car id-and-timer)))
(setq retval `(canceled ,cancel-on-input-retval)))
(t (let ((inhibit-quit nil))
(while t (accept-process-output nil 30))))))
;; In normal operation, continuations for error/success is
;; handled by `jsonrpc--continue'. Timeouts also remove
;; the continuation...
(pcase-let* ((`(,id ,_) id-and-timer))
;; ...but we still have to guard against exist explicit
;; user-quit (C-g) or the `cancel-on-input' case, so
;; discard the continuation.
(jsonrpc--remove connection id (list deferred (current-buffer)))
;; Furthermore, assume a nil `retval' is a quit from
;; `accept-process-output' (either "soft" or "hard," like a
;; double C-g C-g on TTY terminals)
(unless retval
(when cancel-on-quit (funcall cancel-on-quit id)))
;; ...finally, whatever may have happened to this sync
;; request, it might have been holding up any outer
;; "anxious" continuations. The following ensures we
;; call them.
(jsonrpc--continue connection `(:local ,id))))
(cond ((eq 'error (car retval))
(signal 'jsonrpc-error
(cons
(format "request id=%s failed:" (car id-and-timer))
(cdr retval)))))
(cadr retval)))