diff options
| author | Mattias EngdegÄrd | 2025-09-06 10:44:43 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2025-09-07 14:39:24 +0200 |
| commit | c13c620f12e2f874d22715e7b1dcd06bb5ed1930 (patch) | |
| tree | 9fc8c7cdf515309983c00a973d8fb65575dc4519 | |
| parent | 36c8ebe78a048db7886f070168858d457b486caf (diff) | |
| download | emacs-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.el | 54 |
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. | ||
| 1000 | Do 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. |
| 1000 | This hooks runs in the events buffer of every `jsonrpc-connection' | 1014 | This 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 | ||