Skip to content

perform solving by polling clingo with asyncio to handle SIGINT#51338

Draft
cosmicexplorer wants to merge 2 commits intospack:developfrom
cosmicexplorer:solver-subthread
Draft

perform solving by polling clingo with asyncio to handle SIGINT#51338
cosmicexplorer wants to merge 2 commits intospack:developfrom
cosmicexplorer:solver-subthread

Conversation

@cosmicexplorer
Copy link
Copy Markdown
Contributor

@cosmicexplorer cosmicexplorer commented Sep 21, 2025

Problem: interrupting the solver is impossible

I'm hacking away at #51245. In particular see the followup tasks I'm working on at #51245 (comment), which note how the solver is unresponsive to ^C when it triggers the invalid variant condition described in that issue.

It turns that clingo isn't doing anything wrong, but we really need to avoid blocking on the SolveHandle.wait(-1) method. Without spack/spack-packages#1600, the following hangs:

; spack spec icu4c
# hangs forever
^C^C^C^C^C
^C^C^C
# unresponsive to ^C
# requires `kill -s TERM/KILL` from a separate terminal
; spack -d spec icu4c
# produces some debug output before initiating the solve,
# but no output after initiating the async solve

Aside: this is a really frustrating failure mode

I triggered this failure mode by accident trying to add new build variants for python 3.15 --disable-gil, and I triggered it again when trying to build icu4c statically to impress a friend of mine who does packaging for alpine. So until we have a handle on the infinite looping (#51245 narrows it down to variant defaults), I think this will be especially important.

Even once we do fix the infinite looping, this is the one part of the spack run that is completely unresponsive to user input or progress output.

Solution: push the solver to asyncio

  • create spack.llnl.util.subthread to characterize threaded processes which produce output
  • decouple polling for output from executing the process
  • translate a repeated blocking poll into the language of asyncio using a thread pool executor

Result

  • ^C works during solver hangs
  • debug logs to show a sign of life even during infinite looping
  • no performance loss

@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

cosmicexplorer commented Sep 21, 2025

Ok, a few things I need to fix:

  1. signal.set_wakeup_fd() as per pdb.py in cpython requires 3.7+.
  2. After I spent the time to reframe the solve as a stream of progress output, I think the signal handling shouldn't even be part of the same class (which may mean we can remove the special SIGINT handling here altogether).
  3. I think async generators and futures may be the right abstraction for this.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Sep 21, 2025

@cosmicexplorer I just saw this PR, and noticed I was experimenting with the same thing for a different reason. I think we can do what you want in a few lines, see 6b61d2b, since we already perform the solve in a different thread. Let me know if that works for your use case.

@cosmicexplorer cosmicexplorer changed the title perform solving in a separate thread to handle SIGINT perform solving by polling clingo with asyncio to handle SIGINT Sep 22, 2025
@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

@alalazo well, I had a lot of fun figuring out how to make this approach work in asyncio. I think your solution is great! I will leave this as a draft and we can come back to it if we want to coordinate e.g. highly parallel solves.

@cosmicexplorer cosmicexplorer force-pushed the solver-subthread branch 3 times, most recently from 77770a2 to 196eed1 Compare September 22, 2025 03:14
- move to llnl.util.subthread
- now move it back to asp.py
- add docs and justification
- remove future annotations for py36 compat

Signed-off-by: Danny McClanahan <[email protected]>
Signed-off-by: Danny McClanahan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants