aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2025-09-06 10:44:43 +0200
committerMattias EngdegÄrd2025-09-07 14:39:24 +0200
commitc13c620f12e2f874d22715e7b1dcd06bb5ed1930 (patch)
tree9fc8c7cdf515309983c00a973d8fb65575dc4519
parent36c8ebe78a048db7886f070168858d457b486caf (diff)
downloademacs-c13c620f12e2f874d22715e7b1dcd06bb5ed1930.tar.gz
emacs-c13c620f12e2f874d22715e7b1dcd06bb5ed1930.zip
Less expensive jsonrpc logging (bug#79361)
Remove the oldest 1/4 of the jsonrpc events buffer when reaching the size limit instead of just a few lines. This reduces the cost of adding a log entry from O(buffer-size) to O(1). Also make messages forwarded to the events buffer, such as ones sent to stderr from the server process, obey the same limit. * lisp/jsonrpc.el (jsonrpc--limit-buffer-size): New. (jsonrpc--log-event, jsonrpc--forwarding-buffer): Use it.
-rw-r--r--lisp/jsonrpc.el54
1 files changed, 32 insertions, 22 deletions
diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index bb75196cdc8..1ad0a78b1d1 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -995,6 +995,20 @@ TIMEOUT is nil)."
995 fn oops) 995 fn oops)
996 (remove-hook 'jsonrpc-event-hook fn))))))) 996 (remove-hook 'jsonrpc-event-hook fn)))))))
997 997
998(defun jsonrpc--limit-buffer-size (max-size)
999 "Limit the current buffer to MAX-SIZE by eating lines at the beginning.
1000Do nothing if MAX-SIZE is nil."
1001 (when max-size
1002 (while (> (buffer-size) max-size)
1003 (delete-region
1004 (point-min)
1005 (save-excursion
1006 ;; Remove 1/4, so that the cost is O(1) amortised, since each
1007 ;; call to `delete-region' will move the buffer contents twice.
1008 (goto-char (+ (point-min) (/ (buffer-size) 4)))
1009 (forward-line)
1010 (point))))))
1011
998(defvar jsonrpc-event-hook (list #'jsonrpc--log-event) 1012(defvar jsonrpc-event-hook (list #'jsonrpc--log-event)
999 "Hook run when JSON-RPC events are emitted. 1013 "Hook run when JSON-RPC events are emitted.
1000This hooks runs in the events buffer of every `jsonrpc-connection' 1014This hooks runs in the events buffer of every `jsonrpc-connection'
@@ -1071,15 +1085,7 @@ of the API instead.")
1071 (when error 1085 (when error
1072 (setq msg (propertize msg 'face 'error))) 1086 (setq msg (propertize msg 'face 'error)))
1073 (insert-before-markers msg) 1087 (insert-before-markers msg)
1074 ;; Trim the buffer if it's too large 1088 (jsonrpc--limit-buffer-size max))))))
1075 (when max
1076 (save-excursion
1077 (goto-char (point-min))
1078 (while (> (buffer-size) max)
1079 (delete-region (point) (progn (forward-line 1)
1080 (forward-sexp 1)
1081 (forward-line 2)
1082 (point)))))))))))
1083 1089
1084(defun jsonrpc--forwarding-buffer (name prefix conn) 1090(defun jsonrpc--forwarding-buffer (name prefix conn)
1085 "Helper for `jsonrpc-process-connection' helpers. 1091 "Helper for `jsonrpc-process-connection' helpers.
@@ -1093,19 +1099,23 @@ PREFIX to CONN's events buffer."
1093 (add-hook 1099 (add-hook
1094 'after-change-functions 1100 'after-change-functions
1095 (lambda (beg _end _pre-change-len) 1101 (lambda (beg _end _pre-change-len)
1096 (cl-loop initially (goto-char beg) 1102 (let* ((props (slot-value conn '-events-buffer-config))
1097 do (forward-line) 1103 (max (plist-get props :size)))
1098 when (bolp) 1104 (unless (eql max 0)
1099 for line = (buffer-substring 1105 (cl-loop initially (goto-char beg)
1100 (line-beginning-position 0) 1106 do (forward-line)
1101 (line-end-position 0)) 1107 when (bolp)
1102 do (with-current-buffer (jsonrpc-events-buffer conn) 1108 for line = (buffer-substring
1103 (goto-char (point-max)) 1109 (line-beginning-position 0)
1104 (let ((inhibit-read-only t)) 1110 (line-end-position 0))
1105 (insert 1111 do (with-current-buffer (jsonrpc-events-buffer conn)
1106 (propertize (format "%s %s\n" prefix line) 1112 (goto-char (point-max))
1107 'face 'shadow)))) 1113 (let ((inhibit-read-only t))
1108 until (eobp))) 1114 (insert
1115 (propertize (format "%s %s\n" prefix line)
1116 'face 'shadow))
1117 (jsonrpc--limit-buffer-size max)))
1118 until (eobp)))))
1109 nil t)) 1119 nil t))
1110 (current-buffer))) 1120 (current-buffer)))
1111 1121