QL processing needs to become asynchronous

(Bug, Closed -> Duplicate, Priority: Medium, Test Status: No automated tests yet , Reported By Justin du Coeur, )
Summary: This is big and ugly, but will become necessary. QL processing currently happens synchronously, but that's going to become a major scaling problem eventually.
The straw that is breaking the camel's back is User Values. Since these don't live in memory routinely, the functions that use them necessarily involve a DB call. That will slow these functions down by orders of magnitude over ordinary QL functions, and it is eventually going to become crucial that we not block on them.
The correct design isn't entirely obvious, but we're likely going to have to replace the current stack-based design of QL processing with something more explicit, building up a processing state as an immutable data structure. When we come to a blocking function, we store that structure away until the block is released, and then continue.
This is also strongly implies that QL processing shouldn't be done in-line. Instead, we probably should have a pool of QL-processing Actors on each Node, which receive jobs. Important: this needs to exist on each Node so that we aren't tossing SpaceStates over the wall gratuitously! (We might eventually distribute the processing across Nodes, with slave copies of the SpaceState, but that's enough work to do right that we shouldn't do it unless we need to.)