spin_once will process one item in the executor, it may or may not be the thing you expect, however. Sometimes you just want to spin one thing at a time periodically, and don't care what it is.
Other times you want to spin one thing at a time until something has completed, this is where spin_until_future_complete is useful, as it basically does while(future.not_done()) executor.spin_once(). It's a bit more complicated than that, but essentially that's what it is doing. You could do this yourself, so spin_until_future_complete is just a convenience function.
spin_some is slightly different. Basically it spins, executing zero to many items, until it is "idle", basically until there's a time where there is nothing for the executor to do. Some people might assume that spin_some would only process what available when it is called, exiting even if there's more work to be done after a period of time. There's an issue and pull request to try and make it behave that way, but they're still in progress: