Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional timeout warning when waiting for the proof shell #516

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

andyqhan
Copy link

With bad tactics in Coq (#514), Proof General will hang forever (but can be interrupted with C-c C-c or C-c C-x). In response to @hendriktews's workaround suggestion, this PR exposes a variable proof-shell-timeout-warn that, if an integer, enables a minibuffer warning after waiting on the proof shell for more than proof-shell-timeout-warn seconds.

It doesn't fix the core issue, but the minibuffer warning will remind users of using C-c C-c and C-c C-x to cancel scripting.

The text of the warning is "This command is taking a while. Is it malformed? Do C-c C-c or C-c C-x to abort." Default timeout is 30 seconds.

@andyqhan andyqhan marked this pull request as ready for review October 13, 2020 14:38
@Matafou
Copy link
Contributor

Matafou commented Mar 11, 2021

Sorry for the delay, I will review your PR shortly. Thanks for it!

generic/proof-shell.el Outdated Show resolved Hide resolved
generic/proof-script.el Outdated Show resolved Hide resolved
@@ -738,6 +745,11 @@ unless the FLAGS for the command are non-nil (see `proof-action-list')."
;; proof-action-list is empty on error.
(setq proof-action-list nil)
(proof-release-lock)
(unless proof-shell-busy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this test is necessary. Why would the shell be busy if an error is detected? Probably not harmful.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it in, but can remove if you'd like.

Copy link
Contributor

@Matafou Matafou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General remarks. Other remarks in the code.

  • You should probably not make a PR from your own "master" branch. You should define a dedicated branch in you repository instead. No big deal.
  • While testing I noticed that the message is displayed sometimes apparently for no reason. It seems this happens when PG processes comments. Maybe because in this cases PG do not send anything to coq actually, and this gets no response either. Probably a missing cancel-timer somewhere. I will investigate a bit more.
    This almost good I would say.

@Matafou
Copy link
Contributor

Matafou commented Mar 11, 2021

  • Probably a missing cancel-timer somewhere. I will investigate a bit more.

It is just that the timer should not be launched when the semi's type is 'comment.

@andyqhan
Copy link
Author

@Matafou I've implemented your suggestions — thank you so much for the review!

  • You should probably not make a PR from your own "master" branch. You should define a dedicated branch in you repository instead. No big deal.

My bad, I'll make sure to do that in the future.

  • While testing I noticed that the message is displayed sometimes apparently for no reason. It seems this happens when PG processes comments. Maybe because in this cases PG do not send anything to coq actually, and this gets no response either. Probably a missing cancel-timer somewhere. I will investigate a bit more.

I changed the conditional for arming the timer to:

(if (and proof-shell-timeout-warn
         (not (eq (caar semis) 'comment)))

I'm not sure whether this is what you had in mind.

@hendriktews
Copy link
Collaborator

Thanks for your contribution!
In #514 I described an approach that sets and clears the timer for each command sent to Coq. Instead, your approach is to set and clear the timer only once for each asserted region. This is also possible. However, you need to consider two points.

  1. Comments, as pointed out already by @Matafou: If the asserted region consists only of comments, then proof-add-to-queue might process them without calling proof-shell-exec-loop. Checking whether the first element is a comment (as you do now) is not good enough, because the asserted region may consist of a mixture of comments and real commands. If you want to stick to your approach, I suggest to move setting up the timer to proof-add-to-queue after the leading comments have been processed there.
  2. quickly asserting twice: I believe it is possible to assert another region while the previous region is still processing. In this case, you will never kill the timer for the first region.

(if (and proof-shell-timer proof-shell-timeout-warn)
(progn (cancel-timer proof-shell-timer)
(setq proof-shell-timer nil))))

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation seems wrong here. Would it be possible to fix that?

@andyqhan
Copy link
Author

Thank you for the speedy review.

I'm reconsidering the need for this PR, because I can't seem to get the MWE given in #514 to hang (probably because of the fixes in 0fdb1ae, I'm getting Syntax Error: Lexer: Undefined token). However, if the maintainers still think there's a need, I'd be happy to continue working on this feature — it's just that not being able to reproduce the hanging anymore means that I have trouble working on it further.

@Matafou
Copy link
Contributor

Matafou commented Mar 22, 2021

If you want a script where coq still hangs you can use this:

Lemma foobar: True.
Proof.
  idtac.+ }

@andyqhan
Copy link
Author

Ok, I believe I've fixed the issues. I'm not quite sure what to do with the case when someone can assert quickly multiple times in a row (the timer won't start if it's already running — that may help), but it now doesn't start the timer if the processed region was all comments. In order to do this, per @hendriktews 's suggestion, I've moved setting the timer to proof-add-to-queue, and arm the timer only when the length of proof-shell-slurp-comments is less than the length of proof-action-list (that is, when the region isn't only comments). Could someone take a look?

@Matafou
Copy link
Contributor

Matafou commented Apr 1, 2021

It seems to work, but is it really what we expect?
When one launch a big thunk of coq commands, if the global execution of the whole thunk takes more that 30sec we get the message. One would expect that we put a timer on each command. No?

@hendriktews
Copy link
Collaborator

It seems to work, but is it really what we expect?

No. It seems that my comment from March 21, that the approach followed here is also possible, was wrong. I would suggest to follow my outline in #514 instead.

@andyqhan
Copy link
Author

andyqhan commented Apr 3, 2021

I moved the timer setup to proof-shell-insert, which should mean that it is armed per command and not per region. I tried putting it in proof-shell-exec-loop like hendriktews suggested, but it seems that if a command hangs, that function isn't called. In order to deal with the fact that a region can take more than proof-shell-timeout-warn seconds to complete, I cancel the timer before setting it if the timer exists. Also, I'm checking that the argument of proof-shell-insert is a visible command by checking that the callback is 'proof-done-advancing — I'm not sure whether this is the best way.

(I believe those two tests are failing because of some problem fetching from Docker servers? Not sure)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants