-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Actor Feed Loaders #70
Open
EricBAndrews
wants to merge
19
commits into
master
Choose a base branch
from
eric/actor-feed-loaders
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR completely reworks the
FeedLoader
architecture to use native Swiftactor
s for concurrency management. This is achieved by the addition of two new components: theLoadingActor
and theFetcher
.LoadingActor
The
LoadingActor
is anactor
that is responsible for loading. Becauseactor
s are extremely inflexible, this is designed to be as minimal and generic as possible; it can be thought of as the "kernel" of the loading system. TheLoadingActor
defines two operations:load
: loads the next page of itemsreset
: resets the loading stateThe behavior of these operations is subject to the following behavior requirements:
reset
andload
while an existingload
call is awaiting the server responsereset
is called while the actor is loading, the existing load should be immediately cancelledload
is called while the actor is loading, the new load call should be ignoredThese requirements ensure that the frontend is responsive (e.g., refreshing the feed does not require waiting for an existing load to complete just to be thrown out) and duplicate loads (e.g., as caused by scrolling fast and hitting both the normal and the fallback threshold) are ignored.
To support this behavior, the
LoadingActor
stores aloadingTask
. This is an independentTask
that performs the actual server call; if no server call is in progress,loadingTask
is nil.load
spawns this task then awaits its result; theawait
operation frees up the actor to handle newreset
orload
calls. This architecture satisfies the above requirements:load
orreset
operations can be handled as soon as theloadingTask
is spawned.reset
call comes in whileloadingTask
is non-nil, it simply callsTask.cancel()
on theloadingTask
. ThatloadingTask
will return acancelled
status.load
call comes in whileloadingTask
is non-nil,load
returns theignored
status.Fetcher
Swift does not allow inheritance with
actor
s. This rendersLoadingActor
highly inflexible; each fetch use cases requires tracking a unique set of fetch parameters, which is inelegant to handle within theLoadingActor
itself.LoadingActor
is therefore instantiated with aFetcher
: a class which provides thefetchPage
andfetchCursor
methods and handles the unique fetch parameters for each loader. TheFetcher
is stored within theFeedLoader
and passed as a reference into theLoadingActor
, allowing theFeedLoader
to modify fetching behavior (e.g., change the query string for a search fetch).Responsibility Changes
The
FeedLoader
looks largely the same as before, but with much of its operation now delegated to theFetcher
and theLoadingActor
. Most notably, theFeedLoader
'sloadingState
no longer has concurrency management responsibilities. The responsibilities of each component are as follows:FeedLoader
Fetcher
LoadingActor