Subject: bug#69241: closed (Re: bug#69241: Fixed patch issues)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 12 Mar 2024 15:02:02 +0000

Your bug report

#69241: [PATCH] Jsonrpc: improve performance of process filter function

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
69241: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69241
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#69241: Fixed patch issues
From: Eli Zaretskii <[email-masked]>
To: Daniel Pettersson <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Tue, 12 Mar 2024 17:00:26 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: Daniel Pettersson <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Tue, 12 Mar 2024 15:34:20 +0100
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > Should we close this bug now?
> 
> Yes

Thanks, done.

Subject: [PATCH] Jsonrpc: improve performance of process filter function
From: Daniel Pettersson <[email-masked]>
To: [email-masked]
Date: Sun, 18 Feb 2024 02:53:01 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

This was issue was discovered during elpa package dape's development,
where an adapter was sending 72000 notifications on startup which leads
to emacs looping over timer--time-less-p for > 50 seconds and after the
fix for less then 1 second.  The "integrity" of timer order are messed
with but as timer_check runs all of the ripe timers in the same while
loop it only becomes an question of execution order.  This change uses
timer.el internal api `timer--triggered', but this might be fine as it's
tightly coupled with keyboard.

In GNU Emacs 30.0.50 (build 1, aarch64-apple-darwin23.1.0, NS
 appkit-2487.20 Version 14.1.1 (Build 23B81)) of 2023-12-20 built on
 Daniels-Air
Repository revision: 281be72422f42fcc84d43f50723a3e91b7d03cbc
Repository branch: master
Windowing system distributor 'Apple', version 10.3.2487
System Description:  macOS 14.1.1

>From 92eef1a5221dd69dc95a9484eafeacad571246f8 Mon Sep 17 00:00:00 2001
From: Daniel Pettersson <[email-masked]>
Date: Sun, 18 Feb 2024 02:05:46 +0100
Subject: [PATCH] Jsonrpc: improve performance of process filter function

`run-at-time' keeps `timer-list' list sorted by inserting each timer
based on the timer value.  This means that `timer--time-less-p' needs is
executed ~ N*N/2 times for each N pending messages.  This means that
jsonrpc becomes unusable for connections that generate a lot messages at
the same time.

* lisp/jsonrpc.el (Version): Bump to 1.0.25
(jsonrpc--process-filter): Improve performance
---
 lisp/jsonrpc.el | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index 14fe0447008..9a52b5a76cf 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -4,7 +4,7 @@
 
 ;; Author: João Távora <[email-masked]>
 ;; Keywords: processes, languages, extensions
-;; Version: 1.0.24
+;; Version: 1.0.25
 ;; Package-Requires: ((emacs "25.2"))
 
 ;; This is a GNU ELPA :core package.  Avoid functionality that is not
@@ -782,11 +782,22 @@ jsonrpc--process-filter
           ;; non-locally (typically the reply to a request), so do
           ;; this all this processing in top-level loops timer.
           (cl-loop
+           with time = (timer-relative-time nil 0)
            for msg = (pop (process-get proc 'jsonrpc-mqueue)) while msg
-           do (run-at-time 0 nil
-                           (lambda (m) (with-temp-buffer
-                                         (jsonrpc-connection-receive conn m)))
-                           msg)))))))
+           do (let ((timer (timer-create)))
+                (timer-set-time timer time)
+                (timer-set-function timer
+                                    (lambda (conn msg)
+                                      (with-temp-buffer
+                                        (jsonrpc-connection-receive conn msg)))
+                                    (list conn msg))
+                (setf (timer--triggered timer) nil)
+                ;; We're bypassing `timer-activate' due to performance
+                ;; concerns.  `timer-activate' iterates through all
+                ;; timers scheduled to execute before inserting our
+                ;; callback.  While it doesn't maintain the precise
+                ;; order of timers, we should be fine.
+                (setf timer-list (cons timer timer-list)))))))))
 
 (defun jsonrpc--remove (conn id &optional deferred-spec)
   "Cancel CONN's continuations for ID, including its timer, if it exists.
-- 
2.39.3 (Apple Git-145)