I'm not super familiar with rayon; I see that it has a ScopeFifo type, but FIFO is the opposite of what you want. You want something that is LIFO. I see that there's also a Scope type, but it doesn't mention LIFO or FIFO at all, and since you're asking this question, it probably isn't LIFO.
You could check some "is user initiated stuff running" value shared using an Arc<AtomicBool> and sleep in the background processes. This would give the other threads more CPU time.
Another possible approach would be to code up your expensive operations as state machines. A state machine is basically a way to pause something and continue later. This would allow you to keep the state of a partially finished operation in a variable, and continue the task when you want to. Now you can run them on a custom thread pool and just pause the unimportant operation when a user-initiated one comes in.
The state machine solution is basically the future ecosystem, and you could do it using futures, but unfortunately futures aren't really built for expensive computations.