Real inter-pipeline synchronization

fixes #324 

- [x] wrap every pipeline in `spawn()`
  - create sync object at pipeline sources: 
    - [x] ShuffleHashJoin post left/right
    - [x] MemoryScan
    - [x] GroupBy post input
- [x] `wait()` inside of the pipeline task, instead of outside in main task. 
- [x] `wait()` for all pipelines at end of main thread
- constructs with dependences
  - [x] HashJoin
  - [x] ShuffleHashJoin
  - [x] GroupBy