Commit e1c1345
committed
Fetch multiple includes concurrently
When preloading multiple fields, we can get some extra performance by
doing multiple fetches simultaneously.
Consider a query fetching comments, and requesting that ParseServer
preload "post" and "author" pointers:
> GET /classes/Comment?include=post,author
In this case, we first need to fetch the resulting "Comment" documents,
but after that we should be able to fetch the documents referenced by
the `post` and `author` fields of the results simultaneously, as they
don't depend on each other at all.
Things get a little trickier when we have nested fields:
> GET /classes/Comment?include=post,post.author,post.category
To resolve this query, we first need to fetch the related posts, and
only once we've added the data about those posts into the results tree
can we scan it for the `post.author` and `post.category` pointers. But,
once that first fetch is completed, we can unblock both of those nested
queries!
The solution here is to build what is basically a dependency graph out
of promises; each include path blocks while it is waiting for whatever
path it depends on to finish loading. Finally, once we have that graph,
we return a promise that depends on every node in it.
Aside: Technically we only need to depend on leaf nodes, but there
shouldn't be any meaningful difference between waiting on the leafs
and waiting on the entire graph, and this way we don't have to do any
analysis to find the leafs)
It's possible that for degenerate cases (hundreds of includes in a
single query), this could result in performance degradation as many
queries are kicked off in parallel. For the more common case of just a
few top level includes, this should be a noticeable speed up as we
remove a "waterfall" style dependency graph.
Improve readability of `RestQuery.handleInclude`
There's quite a bit of trickiness going on here, so for the benefit of
future maintainers, lets add some documentation and clear up some
variable names.
- Documented the preconditions that we expect when we're entering this
function. These are all met by the current implementation of the
caller, but it's helpful to someone trying to verify the correctness
of this function.
- Added a lengthier description of what is going on with the map of
`promises`
- Renamed some variables to help make their purpose clearer1 parent e43a843 commit e1c1345
1 file changed
+50
-16
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
747 | 747 | | |
748 | 748 | | |
749 | 749 | | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
750 | 764 | | |
751 | 765 | | |
752 | 766 | | |
753 | 767 | | |
754 | 768 | | |
755 | | - | |
756 | | - | |
757 | | - | |
758 | | - | |
759 | | - | |
760 | | - | |
761 | | - | |
762 | | - | |
763 | | - | |
764 | | - | |
765 | | - | |
766 | | - | |
767 | | - | |
768 | | - | |
769 | | - | |
770 | | - | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
771 | 805 | | |
772 | 806 | | |
773 | 807 | | |
| |||
0 commit comments