|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
| 3 | +require "mongoid/contextual/mongo/documents_loader" |
3 | 4 | require "mongoid/contextual/atomic" |
4 | 5 | require "mongoid/contextual/aggregable/mongo" |
5 | 6 | require "mongoid/contextual/command" |
@@ -37,6 +38,8 @@ class Mongo |
37 | 38 | # @attribute [r] view The Mongo collection view. |
38 | 39 | attr_reader :view |
39 | 40 |
|
| 41 | + attr_reader :documents_loader |
| 42 | + |
40 | 43 | # Get the number of documents matching the query. |
41 | 44 | # |
42 | 45 | # @example Get the number of matching documents. |
@@ -777,6 +780,17 @@ def third_to_last! |
777 | 780 | third_to_last || raise_document_not_found_error |
778 | 781 | end |
779 | 782 |
|
| 783 | + # Schedule a task to load documents for the context. |
| 784 | + # |
| 785 | + # Depending on the Mongoid configuration, the scheduled task can be executed |
| 786 | + # immediately on the caller's thread, or can be scheduled for an |
| 787 | + # asynchronous execution. |
| 788 | + # |
| 789 | + # @api private |
| 790 | + def load_async |
| 791 | + @documents_loader ||= DocumentsLoader.new(view, klass, criteria) |
| 792 | + end |
| 793 | + |
780 | 794 | private |
781 | 795 |
|
782 | 796 | # Update the documents for the provided method. |
@@ -844,24 +858,29 @@ def inverse_sorting |
844 | 858 | Hash[sort.map{|k, v| [k, -1*v]}] |
845 | 859 | end |
846 | 860 |
|
847 | | - # Get the documents the context should iterate. This follows 3 rules: |
848 | | - # |
849 | | - # 1. If the query is cached, and we already have documents loaded, use |
850 | | - # them. |
851 | | - # 2. If we are eager loading, then eager load the documents and use |
852 | | - # those. |
853 | | - # 3. Use the query. |
854 | | - # |
855 | | - # @api private |
| 861 | + # Get the documents the context should iterate. |
856 | 862 | # |
857 | | - # @example Get the documents for iteration. |
858 | | - # context.documents_for_iteration |
| 863 | + # If the documents have been already preloaded by `Document::Loader` |
| 864 | + # instance, they will be used. |
859 | 865 | # |
860 | 866 | # @return [ Array<Document> | Mongo::Collection::View ] The docs to iterate. |
| 867 | + # |
| 868 | + # @api private |
861 | 869 | def documents_for_iteration |
862 | | - return view unless eager_loadable? |
863 | | - docs = view.map{ |doc| Factory.from_db(klass, doc, criteria) } |
864 | | - eager_load(docs) |
| 870 | + if @documents_loader |
| 871 | + if @documents_loader.started? |
| 872 | + @documents_loader.value! |
| 873 | + else |
| 874 | + @documents_loader.unschedule |
| 875 | + @documents_loader.execute |
| 876 | + end |
| 877 | + else |
| 878 | + return view unless eager_loadable? |
| 879 | + docs = view.map do |doc| |
| 880 | + Factory.from_db(klass, doc, criteria) |
| 881 | + end |
| 882 | + eager_load(docs) |
| 883 | + end |
865 | 884 | end |
866 | 885 |
|
867 | 886 | # Yield to the document. |
|
0 commit comments