Function: jsonrpc-autoport-bootstrap

jsonrpc-autoport-bootstrap is a byte-compiled function defined in jsonrpc.el.gz.

Signature

(jsonrpc-autoport-bootstrap NAME CONTACT &key CONNECT-ARGS)

Documentation

Use CONTACT to start network server, then connect to it.

Return function suitable for the :PROCESS initarg of jsonrpc-process-connection(var)/jsonrpc-process-connection(fun) (which see).

CONTACT is a list where all the elements are strings except for one, which is usuallky the keyword :autoport.

When the returned function is called it will start a program using a command based on CONTACT, where :autoport is substituted by a locally free network port. Thereafter, a network is made to this port.

Instead of the keyword :autoport, a cons cell (:autoport FORMAT-FN) is also accepted. In that case FORMAT-FN is passed the port number and should return a string used for the substitution.

The internal processes and control buffers are named after NAME.

CONNECT-ARGS are passed as additional arguments to open-network-stream.

Source Code

;; Defined in /usr/src/emacs/lisp/jsonrpc.el.gz
;;;; More convenience utils
(cl-defun jsonrpc-autoport-bootstrap (name contact
                                           &key connect-args)
  "Use CONTACT to start network server, then connect to it.

Return function suitable for the :PROCESS initarg of
`jsonrpc-process-connection' (which see).

CONTACT is a list where all the elements are strings except for
one, which is usuallky the keyword `:autoport'.

When the returned function is called it will start a program
using a command based on CONTACT, where `:autoport' is
substituted by a locally free network port.  Thereafter, a
network is made to this port.

Instead of the keyword `:autoport', a cons cell (:autoport
FORMAT-FN) is also accepted.  In that case FORMAT-FN is passed
the port number and should return a string used for the
substitution.

The internal processes and control buffers are named after NAME.

CONNECT-ARGS are passed as additional arguments to
`open-network-stream'."
  (lambda (conn)
    (let* ((port-probe (make-network-process :name "jsonrpc-port-probe-dummy"
                                             :server t
                                             :host "localhost"
                                             :service 0))
           (port-number (unwind-protect
                            (process-contact port-probe :service)
                          (delete-process port-probe)))
           (inferior-buffer (jsonrpc--forwarding-buffer
                             (format " *%s inferior output*" name)
                             "[inferior]"
                             conn))
           (cmd (cl-loop for e in contact
                         if (eq e :autoport) collect (format "%s" port-number)
                         else if (eq (car-safe e) :autoport)
                         collect (funcall (cdr e) port-number)
                         else collect e))
           inferior np)
      (unwind-protect
          (progn
            (message "[jsonrpc] Attempting to start `%s'"
                     (string-join cmd " "))
            (setq inferior
                  (make-process
                   :name (format "inferior (%s)" name)
                   :buffer inferior-buffer
                   :noquery t
                   :command cmd))
            (setq np
                  (cl-loop
                   repeat 10 for i from 0
                   do (accept-process-output nil 0.5)
                   while (process-live-p inferior)
                   do (message
                       "[jsonrpc] %sTrying to connect to localhost:%s (attempt %s)"
                       (if (zerop i) "Started.  " "")
                       port-number (1+ i))
                   thereis (ignore-errors
                             (apply #'open-network-stream
                                    (format "autostart (%s)" name)
                                    nil
                                    "localhost" port-number connect-args))))
            (setf (slot-value conn '-autoport-inferior) inferior)
            np)
        (cond ((and (process-live-p np)
                    (process-live-p inferior))
               (message "[jsonrpc] Done, connected to %s!" port-number))
              (t
               (when inferior (delete-process inferior))
               (when np (delete-process np))
               (error "[jsonrpc] Could not start and/or connect")))))))