From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Newsgroups: gmane.emacs.bugs Subject: bug#45117: 28.0.50; process-send-string mysteriously exiting non-locally when called from timer Date: Thu, 10 Dec 2020 20:12:11 +0000 Message-ID: <87czzh1kv8.fsf@gmail.com> References: <87h7ow4j4o.fsf@gmail.com> <83mtyo71dh.fsf@gnu.org> <877dps47ge.fsf@gmail.com> <83360g6xlt.fsf@gnu.org> <87im9b2pds.fsf@gmail.com> <83k0tr5700.fsf@gnu.org> <87360d3dud.fsf@gmail.com> <83eejx4rd6.fsf@gnu.org> <87r1nx1vtd.fsf@gmail.com> <87mtyl1v6y.fsf@gmail.com> <87h7ot1ona.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="8692"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: 45117@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Dec 10 21:14:02 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1knSKA-00028U-Ee for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 10 Dec 2020 21:14:02 +0100 Original-Received: from localhost ([::1]:51924 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1knSK9-0006wI-DU for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 10 Dec 2020 15:14:01 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39642) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1knSJC-0006u2-DF for bug-gnu-emacs@gnu.org; Thu, 10 Dec 2020 15:13:07 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:56053) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1knSJB-0000Xx-V6 for bug-gnu-emacs@gnu.org; Thu, 10 Dec 2020 15:13:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1knSJB-0008BS-QN for bug-gnu-emacs@gnu.org; Thu, 10 Dec 2020 15:13:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 10 Dec 2020 20:13:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 45117 X-GNU-PR-Package: emacs Original-Received: via spool by 45117-submit@debbugs.gnu.org id=B45117.160763114331411 (code B ref 45117); Thu, 10 Dec 2020 20:13:01 +0000 Original-Received: (at 45117) by debbugs.gnu.org; 10 Dec 2020 20:12:23 +0000 Original-Received: from localhost ([127.0.0.1]:39366 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1knSIZ-0008AX-D5 for submit@debbugs.gnu.org; Thu, 10 Dec 2020 15:12:23 -0500 Original-Received: from mail-wr1-f43.google.com ([209.85.221.43]:42630) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1knSIW-0008AJ-Qa for 45117@debbugs.gnu.org; Thu, 10 Dec 2020 15:12:21 -0500 Original-Received: by mail-wr1-f43.google.com with SMTP id m5so6784871wrx.9 for <45117@debbugs.gnu.org>; Thu, 10 Dec 2020 12:12:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=gxXakKvIdJWdBqKzd/UhoxYCpHBuYS8NWCVtCoc/SXA=; b=NVpafzTi+05WsurmTdqyR1SerCUA9xzrWuVer/kacwARpqErJzX/6TJg0Dd340cVKM yC/e8ZI5VqPgmQDiwD3V4/K9sBnZQ53Jd1CCKNQfYhtL8JFpmuBFi84TeeIZTfO0MAes cNccGKmW63qelBgshr+bGbYsATEkVC8CGFl3lZ+uNbxUC13KiazRRx51dva7na1dkRBD 56uXbfGzNy0zT7HGAgbDdLac1mqS2R4RzyQklCUkG7gsxZrtxVbLToFtkq0P9UUK6jGi j8lsQS2INvDadyy5b7EaheCZgq+u95gl4o6Es1LTNa/su5VDbgewQsTK/MlLk9YC5E/K Ilig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=gxXakKvIdJWdBqKzd/UhoxYCpHBuYS8NWCVtCoc/SXA=; b=JoOtoSWiHMdsql5paV4a3oI285RjcuRSGyyHyXHOBwUsSNMewXoHdGC058BuI2lHLU /wTDxnhKgFoHlUhI13+pQXisn/SZ7pqrwFPADQaBO6eKSaltILuKLsr98M4hOlb6sklG id0/feMtOGPK9MmP3LL/BK+jFz3ycqvdM+Ps+ZQD08sVuJmmwT1PQr96+4RouXTmShBo ZqmobQjXAAH/T2NNNiVXYeSddM+uIiTYY304UUzQDKbo8XUMn69uIdiCTVGnf1do7t7g oRtuIXgxi6gejHBl80O3/d8/YYAVJEwv5KYMgikGsIXb5pXUp8G1+udyBGY74hH5PTWH 6WdA== X-Gm-Message-State: AOAM533MK1XvwtUvmy6ufhyi50CCyBg7geBDpQiqAcVUPI+mQGzfez/t d8xJlAUINsWLhGH0681LNeJAqLfqhBg= X-Google-Smtp-Source: ABdhPJxl4C3ACF213fzpLYdyCOExabRyg5DrdHWgMVE83aShFRdMNSsS/B5pgPtw6kioGX0Tqx/FvQ== X-Received: by 2002:adf:9cc6:: with SMTP id h6mr10032997wre.341.1607631134434; Thu, 10 Dec 2020 12:12:14 -0800 (PST) Original-Received: from krug ([87.196.174.9]) by smtp.gmail.com with ESMTPSA id o17sm11783645wrg.32.2020.12.10.12.12.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Dec 2020 12:12:12 -0800 (PST) In-Reply-To: (Stefan Monnier's message of "Thu, 10 Dec 2020 14:46:02 -0500") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:195697 Archived-At: Stefan Monnier writes: >>> Right. And `while-no-input` should only wrap the execution of A, so if >>> A doesn't complete, then presumably none of C nor B will want to be >>> executed, which seems OK. >> >> We are miscommunicating. In these programs, B needs to be atomic with >> A. When you send things into an external process, only the most naive >> of external communication protocol replies immediately and synchronously >> to the thing you just sent. For those super simple things, like "cat" >> and "grep", your model works. > > No, I was no presuming such a simple model, actually. I was really > thinking about "send data to the LSP server then get some answer > a second or more later". Right, so in LSP it's perfectly possible to send three requests in a row, say reqX, reqY and reqZ and get three replies in a completely different order repZ, repX, repY. How to you match each reply to each request? >>> closes the pipe in case we're exiting before having sent all the data >>> (that's a good idea to do also in case a bug signals an error). >> Again, this killing of the subprocess assumes the trivial case of a unix >> utility. > > That's just for lack of a vocabulary to say abstractly what I meant. > I understand that in many cases you may want to keep the subprocess (and > pipe) open, in which case you'll have to do something else, but that > "something" will depend on lots of details of the circumstance. process_send_string may send things in "bunches", I read in the docstring, but it will not (and should not) be interrupted. At least I see no reason to. When it returns, sending should be done. Either that or it should exit loudly with an error that one can catch, in which case one should retry the whole thing. >>> The exact same problem affects all normal Elisp code when the user hits >>> C-g, so I think the better path forward is to make sure it's "easy and >>> natural" to write code which reacts correctly when it's aborted at some >>> arbitrary time. We usually get that via `unwind-protect`, but if it's >>> not enough we should develop better solutions rather than shy away from >>> `quit`. >> I get what you're saying, but there's a presumably reason we bind >> inhibit-quit to t in timers (Eli?), and it's that that code isn't >> triggered by a direct action of he user. > > Indeed, we bind inhibit-quit there because when the users hit C-g they > presumably have no idea whether a timer or process filter happens to be > running right now, so they don't actually mean "stop this timer" but > something entirely different (such as run the command `keyboard-quit`). I see, and you you think it is different for "input something", because that in ElDoc, would in principle invalidate the context of the documentation request. But that is not always so. And I think it's too eager of ElDoc to try to do that so early and so brutally. It's better to leave it to the callback handlers, which we have now. That's a much safer spot to know if the answer we just got still makes sense. Or if we're in a hurry, we let the backend know asap. > Note that in return we expect timers and process filters to run only for > a very short amount of time, so that we can still react to C-g > promptly. Fine, and so they should. Much like Flymake stuff. That's in the contract :-) > The contract is different for timer functions than it is for eldoc > functions, yes. This is because the expectation is that eldoc functions > may run for a non-negligible amount of time. Why do you have that expectation? Any particular example in the wild? > Maybe we should change that so it's up to the individual eldoc function > to use `while-no-input` if it needs it, but I'm not sure we've reached > that conclusion yet ;-) It was, after all, the status quo after you changed it for 27.1. Perhaps you had a rationale? >> Yes, there is that too. While-no-input has all those Heisenbergian >> effects to add to it. But this was no heisenberg, I think. I was >> pressing C-n the whole time, so that's "input". > > OK, so `while-no-input` did its job correctly in your case. Good. > Now the next question is: given that the user has hit `C-n` how should > we make sure Emacs responds to it as soon as possible even though it's > currently in the middle of sending a command to an LSP subprocess? > > Is this "sending" expected to never take a long time (in which case > maybe using `inhibit-quit` could be the better answer)? That's what I did, yes. Yes, it's expected to be quick or fail fast. > What's the alternative: what could the Elisp code do to abort the > communication as quickly as possible (without leaving the subprocess in > an inconsistent state and without forcing a costly restart of that > subprocess)? If the protocol doesn't offer any way to abort a command, > maybe it could stash the rest of the data to be sent on some list of > pending data so they'll be sent later asynchronously (and remember that > the answer to that command is probably to be ignored because the user > has moved on)? The protocol could offer an optional abort() switch, yes. ElDoc would raise a flag and say: "hey backends, what you were doing is now useless". We'd see about the implementation, there is likely more than one approach, but a dynamic variable accessed by an (eldoc-aborted-p) seems easiest. I personal don't know of many places where I would use it, or where it would bring an advantage in terms of speed. For example, in responsive completion, I've been doing fine with discarding loads and loads of carefully prepared, now invalid, completions. Fine in terms of speed/responsiveness. But maybe one wishes to save power, which is quite legitimate. Bottom line is, in my opinion, this ElDoc-to-backend abort signal should be controlled, it shouldn't be an unhandleable kill signal. That's asking for trouble. I'd be very suprised if the SLIME people don't start getting this too after they upgrade to 27.1. And maybe the CIDER and Elpy people too? Don't know about Eglot, actually, but I think it's possible yes. All depends on `eldoc-idle-delay`. If it's a low value, it's much much more likely. Since we start with 0.5, we should be OK. Jo=C3=A3o