emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: jsonrpc.el closer to merging


From: João Távora
Subject: Re: jsonrpc.el closer to merging
Date: Mon, 11 Jun 2018 23:26:34 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

João Távora <address@hidden> writes:

>  Thanks. The context is that I'm trying to see what I need to change to use 
> your library.
>  I have code in which the server responds with progress information as it 
> processes a query.  For example
>
>  -> (id=xyz) Compute \pi to 15 decimals
>  <- (id=xyz, progress) 10% done
>  <- (id=xyz, progress) 60% done
>  <- (id=xyz, response) 3.141592653589793
>
>  The same lambda gets invoked three times, twice with 'progress and a 
> message, and once with 'done and a number.
>  Is there a way to model this is json-rpc.el?
>  
> Hmm, I see.  No the library doesn't allow this (and neither does
> JSONRPC, I think)
>
> Why don't you tell me, in pseudo-code, how you would like it to work?
> Perhaps we can add that as a JSONRPC extension (there's a version 
> that I'm not using).

I though a bit more about this and your use case seems to be quite
reasonable.

First, when I sand "there's a version", I meant "there's a version
field" that I'm not using, it's usually the string "2.0". But if we *do*
use it, we can set it to something like 2.0-EMACS which means a
backward-compatible extension to the JSONRPC protocol.

In this extension, responses can have a :PARTIAL field, and the endpoint
receiving such a request should expect more responses with that ID until
a final response with the regular :RESULT field comes in.

What do you think?

I implemented this in the 'multi-response-requests' branch of
address@hidden:joaotavora/eglot.

Here's an example usage from the automated tests file jsonrpc-tests.el:

In this fixture the server responds thrice with partials 1 2 and 3
before sending the actual results.  You can pass :partial-handler to
jsonrpc-request and it will get called with the partial result (while
the function is still blocking).

Or you can pass a more generic SUCCESS-FN to jsonrpc-async-request.

(ert-deftest partial-replies ()
  "Test some basic partial replies."
  (jsonrpc--with-emacsrpc-fixture (conn :partial-responses '(1 2 3))
    (should-error
     (= 42 (jsonrpc-request conn '+ [40 2])))
    (should
     (= 42 (jsonrpc-request conn '+ [40 2] :jsonrpc "2.0-EMACS")))
    (should
     (let ((counter 0))
       (= 42 (jsonrpc-request
              conn '+ [40 2]
              :jsonrpc "2.0-EMACS"
              :partial-handler (lambda (partial)
                                 (should (= (cl-incf counter) partial)))))))
    (catch 'done
      (let ((counter 0))
        (jsonrpc-async-request conn '+ [40 2] :jsonrpc "2.0-EMACS"
                               :success-fn
                               (lambda (result &optional partial)
                                 (when result
                                   (should (null partial))
                                   (should (= result 42))
                                   (throw 'done nil))
                                 (when partial
                                   (should (null result))
                                   (should (= (cl-incf counter) partial)))))
        ;; Need this so that the test keeps running a little bit
        (while (jsonrpc-running-p conn) (accept-process-output nil 3))))))





reply via email to

[Prev in Thread] Current Thread [Next in Thread]