diff options
author | 2023-10-23 10:58:13 +0100 | |
---|---|---|
committer | 2023-10-23 10:58:13 +0100 | |
commit | 69ba9a79a13b21af98d67bbd0802aecb49147f3f (patch) | |
tree | f9dcd19ff6ef3711aadb684633cd0100fceb6b27 /internal/federation/dereferencing | |
parent | [chore]: Bump github.com/coreos/go-oidc/v3 from 3.6.0 to 3.7.0 (#2284) (diff) | |
download | gotosocial-69ba9a79a13b21af98d67bbd0802aecb49147f3f.tar.xz |
[chore] de-interface{} the federator and dereferencer structs (#2285)
* de-interface{} the federator and dereferencer structs
* fix broken type signatures
Diffstat (limited to 'internal/federation/dereferencing')
-rw-r--r-- | internal/federation/dereferencing/account.go | 35 | ||||
-rw-r--r-- | internal/federation/dereferencing/announce.go | 2 | ||||
-rw-r--r-- | internal/federation/dereferencing/collectionpage.go | 2 | ||||
-rw-r--r-- | internal/federation/dereferencing/dereferencer.go | 68 | ||||
-rw-r--r-- | internal/federation/dereferencing/emoji.go | 4 | ||||
-rw-r--r-- | internal/federation/dereferencing/finger.go | 2 | ||||
-rw-r--r-- | internal/federation/dereferencing/handshake.go | 6 | ||||
-rw-r--r-- | internal/federation/dereferencing/instance.go | 2 | ||||
-rw-r--r-- | internal/federation/dereferencing/media.go | 2 | ||||
-rw-r--r-- | internal/federation/dereferencing/status.go | 29 | ||||
-rw-r--r-- | internal/federation/dereferencing/thread.go | 12 |
11 files changed, 63 insertions, 101 deletions
diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 04efc464f..f94dbaffa 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -60,8 +60,10 @@ func accountUpToDate(account *gtsmodel.Account) bool { return false } -// GetAccountByURI: implements Dereferencer{}.GetAccountByURI. -func (d *deref) GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) { +// GetAccountByURI will attempt to fetch an accounts by its URI, first checking the database. In the case of a newly-met remote model, or a remote model +// whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority account information +// may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced. +func (d *Dereferencer) GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) { // Fetch and dereference account if necessary. account, apubAcc, err := d.getAccountByURI(ctx, requestUser, @@ -84,7 +86,7 @@ func (d *deref) GetAccountByURI(ctx context.Context, requestUser string, uri *ur } // getAccountByURI is a package internal form of .GetAccountByURI() that doesn't bother dereferencing featured posts on update. -func (d *deref) getAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) { +func (d *Dereferencer) getAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) { var ( account *gtsmodel.Account uriStr = uri.String() @@ -157,8 +159,10 @@ func (d *deref) getAccountByURI(ctx context.Context, requestUser string, uri *ur return latest, apubAcc, nil } -// GetAccountByUsernameDomain: implements Dereferencer{}.GetAccountByUsernameDomain. -func (d *deref) GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error) { +// GetAccountByUsernameDomain will attempt to fetch an accounts by its username@domain, first checking the database. In the case of a newly-met remote model, +// or a remote model whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority +// account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced. +func (d *Dereferencer) GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error) { if domain == config.GetHost() || domain == config.GetAccountDomain() { // We do local lookups using an empty domain, // else it will fail the db search below. @@ -224,8 +228,10 @@ func (d *deref) GetAccountByUsernameDomain(ctx context.Context, requestUser stri return latest, apubAcc, nil } -// RefreshAccount: implements Dereferencer{}.RefreshAccount. -func (d *deref) RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error) { +// RefreshAccount updates the given account if remote and last_fetched is beyond fetch interval, or if force is set. An updated account model is returned, +// but in the case of dereferencing, some low-priority account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). +// An ActivityPub object indicates the account was dereferenced (i.e. updated). +func (d *Dereferencer) RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error) { // Check whether needs update (and not forced). if accountUpToDate(account) && !force { return account, nil, nil @@ -264,8 +270,9 @@ func (d *deref) RefreshAccount(ctx context.Context, requestUser string, account return latest, apubAcc, nil } -// RefreshAccountAsync: implements Dereferencer{}.RefreshAccountAsync. -func (d *deref) RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) { +// RefreshAccountAsync enqueues the given account for an asychronous update fetching, if last_fetched is beyond fetch interval, or if forcc is set. +// This is a more optimized form of manually enqueueing .UpdateAccount() to the federation worker, since it only enqueues update if necessary. +func (d *Dereferencer) RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) { // Check whether needs update (and not forced). if accountUpToDate(account) && !force { return @@ -294,7 +301,7 @@ func (d *deref) RefreshAccountAsync(ctx context.Context, requestUser string, acc } // enrichAccount will enrich the given account, whether a new barebones model, or existing model from the database. It handles necessary dereferencing, webfingering etc. -func (d *deref) enrichAccount(ctx context.Context, requestUser string, uri *url.URL, account *gtsmodel.Account, apubAcc ap.Accountable) (*gtsmodel.Account, ap.Accountable, error) { +func (d *Dereferencer) enrichAccount(ctx context.Context, requestUser string, uri *url.URL, account *gtsmodel.Account, apubAcc ap.Accountable) (*gtsmodel.Account, ap.Accountable, error) { // Pre-fetch a transport for requesting username, used by later deref procedures. tsport, err := d.transportController.NewTransportForUsername(ctx, requestUser) if err != nil { @@ -472,7 +479,7 @@ func (d *deref) enrichAccount(ctx context.Context, requestUser string, uri *url. return latestAcc, apubAcc, nil } -func (d *deref) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error { +func (d *Dereferencer) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error { if latestAcc.AvatarRemoteURL == "" { // No avatar set on newest model, leave // latest avatar attachment ID empty. @@ -562,7 +569,7 @@ func (d *deref) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.T return nil } -func (d *deref) fetchRemoteAccountHeader(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error { +func (d *Dereferencer) fetchRemoteAccountHeader(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error { if latestAcc.HeaderRemoteURL == "" { // No header set on newest model, leave // latest header attachment ID empty. @@ -652,7 +659,7 @@ func (d *deref) fetchRemoteAccountHeader(ctx context.Context, tsport transport.T return nil } -func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gtsmodel.Account, requestingUsername string) (bool, error) { +func (d *Dereferencer) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gtsmodel.Account, requestingUsername string) (bool, error) { maybeEmojis := targetAccount.Emojis maybeEmojiIDs := targetAccount.EmojiIDs @@ -766,7 +773,7 @@ func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gts // dereferenceAccountFeatured dereferences an account's featuredCollectionURI (if not empty). For each discovered status, this status will // be dereferenced (if necessary) and marked as pinned (if necessary). Then, old pins will be removed if they're not included in new pins. -func (d *deref) dereferenceAccountFeatured(ctx context.Context, requestUser string, account *gtsmodel.Account) error { +func (d *Dereferencer) dereferenceAccountFeatured(ctx context.Context, requestUser string, account *gtsmodel.Account) error { uri, err := url.Parse(account.FeaturedCollectionURI) if err != nil { return err diff --git a/internal/federation/dereferencing/announce.go b/internal/federation/dereferencing/announce.go index e479e41b1..22c33685a 100644 --- a/internal/federation/dereferencing/announce.go +++ b/internal/federation/dereferencing/announce.go @@ -27,7 +27,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) -func (d *deref) DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error { +func (d *Dereferencer) DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error { if announce.BoostOf == nil { // we can't do anything unfortunately return errors.New("DereferenceAnnounce: no URI to dereference") diff --git a/internal/federation/dereferencing/collectionpage.go b/internal/federation/dereferencing/collectionpage.go index dc4ac7b4b..dc5c68273 100644 --- a/internal/federation/dereferencing/collectionpage.go +++ b/internal/federation/dereferencing/collectionpage.go @@ -30,7 +30,7 @@ import ( ) // dereferenceCollectionPage returns the activitystreams CollectionPage at the specified IRI, or an error if something goes wrong. -func (d *deref) dereferenceCollectionPage(ctx context.Context, username string, pageIRI *url.URL) (ap.CollectionPageIterator, error) { +func (d *Dereferencer) dereferenceCollectionPage(ctx context.Context, username string, pageIRI *url.URL) (ap.CollectionPageIterator, error) { if blocked, err := d.state.DB.IsDomainBlocked(ctx, pageIRI.Host); blocked || err != nil { return nil, gtserror.Newf("domain %s is blocked", pageIRI.Host) } diff --git a/internal/federation/dereferencing/dereferencer.go b/internal/federation/dereferencing/dereferencer.go index 6248aa2c1..a5c68bd80 100644 --- a/internal/federation/dereferencing/dereferencer.go +++ b/internal/federation/dereferencing/dereferencer.go @@ -18,72 +18,19 @@ package dereferencing import ( - "context" "net/url" "sync" "codeberg.org/gruf/go-mutexes" - "github.com/superseriousbusiness/gotosocial/internal/ap" - "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/media" "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/transport" "github.com/superseriousbusiness/gotosocial/internal/typeutils" ) -// Dereferencer wraps logic and functionality for doing dereferencing of remote accounts, statuses, etc, from federated instances. -type Dereferencer interface { - // GetAccountByURI will attempt to fetch an accounts by its URI, first checking the database. In the case of a newly-met remote model, or a remote model - // whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority account information - // may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced. - GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) - - // GetAccountByUsernameDomain will attempt to fetch an accounts by its username@domain, first checking the database. In the case of a newly-met remote model, - // or a remote model whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority - // account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced. - GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error) - - // RefreshAccount updates the given account if remote and last_fetched is beyond fetch interval, or if force is set. An updated account model is returned, - // but in the case of dereferencing, some low-priority account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). - // An ActivityPub object indicates the account was dereferenced (i.e. updated). - RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error) - - // RefreshAccountAsync enqueues the given account for an asychronous update fetching, if last_fetched is beyond fetch interval, or if forcc is set. - // This is a more optimized form of manually enqueueing .UpdateAccount() to the federation worker, since it only enqueues update if necessary. - RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) - - // GetStatusByURI will attempt to fetch a status by its URI, first checking the database. In the case of a newly-met remote model, or a remote model - // whose last_fetched date is beyond a certain interval, the status will be dereferenced. In the case of dereferencing, some low-priority status information - // may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the status thread. An ActivityPub object indicates the status was dereferenced. - GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) - - // RefreshStatus updates the given status if remote and last_fetched is beyond fetch interval, or if force is set. An updated status model is returned, - // but in the case of dereferencing, some low-priority status information may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the - // status thread. An ActivityPub object indicates the status was dereferenced (i.e. updated). - RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error) - - // RefreshStatusAsync enqueues the given status for an asychronous update fetching, if last_fetched is beyond fetch interval, or if force is set. - // This is a more optimized form of manually enqueueing .UpdateStatus() to the federation worker, since it only enqueues update if necessary. - RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) - - // DereferenceStatusAncestors iterates upwards from the given status, using InReplyToURI, to ensure that as many parent statuses as possible are dereferenced. - DereferenceStatusAncestors(ctx context.Context, requestUser string, status *gtsmodel.Status) error - - // DereferenceStatusDescendents iterates downwards from the given status, using its replies, to ensure that as many children statuses as possible are dereferenced. - DereferenceStatusDescendants(ctx context.Context, requestUser string, statusIRI *url.URL, parent ap.Statusable) error - - GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) - - DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error - - GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) - - GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error) - - Handshaking(username string, remoteAccountID *url.URL) bool -} - -type deref struct { +// Dereferencer wraps logic and functionality for doing dereferencing +// of remote accounts, statuses, etc, from federated instances. +type Dereferencer struct { state *state.State converter *typeutils.Converter transportController transport.Controller @@ -99,8 +46,13 @@ type deref struct { } // NewDereferencer returns a Dereferencer initialized with the given parameters. -func NewDereferencer(state *state.State, converter *typeutils.Converter, transportController transport.Controller, mediaManager *media.Manager) Dereferencer { - return &deref{ +func NewDereferencer( + state *state.State, + converter *typeutils.Converter, + transportController transport.Controller, + mediaManager *media.Manager, +) Dereferencer { + return Dereferencer{ state: state, converter: converter, transportController: transportController, diff --git a/internal/federation/dereferencing/emoji.go b/internal/federation/dereferencing/emoji.go index 3ce3c7f10..2d86da663 100644 --- a/internal/federation/dereferencing/emoji.go +++ b/internal/federation/dereferencing/emoji.go @@ -30,7 +30,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/media" ) -func (d *deref) GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error) { +func (d *Dereferencer) GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error) { var ( shortcodeDomain = shortcode + "@" + domain processingEmoji *media.ProcessingEmoji @@ -88,7 +88,7 @@ func (d *deref) GetRemoteEmoji(ctx context.Context, requestingUsername string, r return processingEmoji, nil } -func (d *deref) populateEmojis(ctx context.Context, rawEmojis []*gtsmodel.Emoji, requestingUsername string) ([]*gtsmodel.Emoji, error) { +func (d *Dereferencer) populateEmojis(ctx context.Context, rawEmojis []*gtsmodel.Emoji, requestingUsername string) ([]*gtsmodel.Emoji, error) { // At this point we should know: // * the AP uri of the emoji // * the domain of the emoji diff --git a/internal/federation/dereferencing/finger.go b/internal/federation/dereferencing/finger.go index fff079327..a81afa5ea 100644 --- a/internal/federation/dereferencing/finger.go +++ b/internal/federation/dereferencing/finger.go @@ -30,7 +30,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/util" ) -func (d *deref) fingerRemoteAccount(ctx context.Context, transport transport.Transport, targetUsername string, targetHost string) (accountDomain string, accountURI *url.URL, err error) { +func (d *Dereferencer) fingerRemoteAccount(ctx context.Context, transport transport.Transport, targetUsername string, targetHost string) (accountDomain string, accountURI *url.URL, err error) { b, err := transport.Finger(ctx, targetUsername, targetHost) if err != nil { err = fmt.Errorf("fingerRemoteAccount: error fingering @%s@%s: %s", targetUsername, targetHost, err) diff --git a/internal/federation/dereferencing/handshake.go b/internal/federation/dereferencing/handshake.go index 96d8d349f..1180ff140 100644 --- a/internal/federation/dereferencing/handshake.go +++ b/internal/federation/dereferencing/handshake.go @@ -21,7 +21,7 @@ import ( "net/url" ) -func (d *deref) Handshaking(username string, remoteAccountID *url.URL) bool { +func (d *Dereferencer) Handshaking(username string, remoteAccountID *url.URL) bool { d.handshakesMu.Lock() defer d.handshakesMu.Unlock() @@ -51,7 +51,7 @@ func (d *deref) Handshaking(username string, remoteAccountID *url.URL) bool { return false } -func (d *deref) startHandshake(username string, remoteAccountID *url.URL) { +func (d *Dereferencer) startHandshake(username string, remoteAccountID *url.URL) { d.handshakesMu.Lock() defer d.handshakesMu.Unlock() @@ -68,7 +68,7 @@ func (d *deref) startHandshake(username string, remoteAccountID *url.URL) { d.handshakes[username] = remoteIDs } -func (d *deref) stopHandshake(username string, remoteAccountID *url.URL) { +func (d *Dereferencer) stopHandshake(username string, remoteAccountID *url.URL) { d.handshakesMu.Lock() defer d.handshakesMu.Unlock() diff --git a/internal/federation/dereferencing/instance.go b/internal/federation/dereferencing/instance.go index 742239637..90ce074cd 100644 --- a/internal/federation/dereferencing/instance.go +++ b/internal/federation/dereferencing/instance.go @@ -25,7 +25,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) -func (d *deref) GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) { +func (d *Dereferencer) GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) { if blocked, err := d.state.DB.IsDomainBlocked(ctx, remoteInstanceURI.Host); blocked || err != nil { return nil, fmt.Errorf("GetRemoteInstance: domain %s is blocked", remoteInstanceURI.Host) } diff --git a/internal/federation/dereferencing/media.go b/internal/federation/dereferencing/media.go index 315da1c39..15aa4bb08 100644 --- a/internal/federation/dereferencing/media.go +++ b/internal/federation/dereferencing/media.go @@ -26,7 +26,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/media" ) -func (d *deref) GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) { +func (d *Dereferencer) GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) { if accountID == "" { return nil, fmt.Errorf("GetRemoteMedia: account ID was empty") } diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index 84316f3a9..bb6a8002c 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -52,8 +52,10 @@ func statusUpToDate(status *gtsmodel.Status) bool { return false } -// GetStatus: implements Dereferencer{}.GetStatus(). -func (d *deref) GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) { +// GetStatusByURI will attempt to fetch a status by its URI, first checking the database. In the case of a newly-met remote model, or a remote model +// whose last_fetched date is beyond a certain interval, the status will be dereferenced. In the case of dereferencing, some low-priority status information +// may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the status thread. An ActivityPub object indicates the status was dereferenced. +func (d *Dereferencer) GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) { // Fetch and dereference status if necessary. status, apubStatus, err := d.getStatusByURI(ctx, requestUser, @@ -74,7 +76,7 @@ func (d *deref) GetStatusByURI(ctx context.Context, requestUser string, uri *url } // getStatusByURI is a package internal form of .GetStatusByURI() that doesn't bother dereferencing the whole thread on update. -func (d *deref) getStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) { +func (d *Dereferencer) getStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) { var ( status *gtsmodel.Status uriStr = uri.String() @@ -146,8 +148,10 @@ func (d *deref) getStatusByURI(ctx context.Context, requestUser string, uri *url return latest, apubStatus, nil } -// RefreshStatus: implements Dereferencer{}.RefreshStatus(). -func (d *deref) RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error) { +// RefreshStatus updates the given status if remote and last_fetched is beyond fetch interval, or if force is set. An updated status model is returned, +// but in the case of dereferencing, some low-priority status information may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the +// status thread. An ActivityPub object indicates the status was dereferenced (i.e. updated). +func (d *Dereferencer) RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error) { // Check whether needs update. if !force && statusUpToDate(status) { return status, nil, nil @@ -178,8 +182,9 @@ func (d *deref) RefreshStatus(ctx context.Context, requestUser string, status *g return latest, apubStatus, nil } -// RefreshStatusAsync: implements Dereferencer{}.RefreshStatusAsync(). -func (d *deref) RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) { +// RefreshStatusAsync enqueues the given status for an asychronous update fetching, if last_fetched is beyond fetch interval, or if force is set. +// This is a more optimized form of manually enqueueing .UpdateStatus() to the federation worker, since it only enqueues update if necessary. +func (d *Dereferencer) RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) { // Check whether needs update. if statusUpToDate(status) { return @@ -208,7 +213,7 @@ func (d *deref) RefreshStatusAsync(ctx context.Context, requestUser string, stat // enrichStatus will enrich the given status, whether a new // barebones model, or existing model from the database. // It handles necessary dereferencing, database updates, etc. -func (d *deref) enrichStatus( +func (d *Dereferencer) enrichStatus( ctx context.Context, requestUser string, uri *url.URL, @@ -329,7 +334,7 @@ func (d *deref) enrichStatus( return latestStatus, apubStatus, nil } -func (d *deref) fetchStatusMentions(ctx context.Context, requestUser string, existing, status *gtsmodel.Status) error { +func (d *Dereferencer) fetchStatusMentions(ctx context.Context, requestUser string, existing, status *gtsmodel.Status) error { // Allocate new slice to take the yet-to-be created mention IDs. status.MentionIDs = make([]string, len(status.Mentions)) @@ -405,7 +410,7 @@ func (d *deref) fetchStatusMentions(ctx context.Context, requestUser string, exi return nil } -func (d *deref) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) error { +func (d *Dereferencer) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) error { // Allocate new slice to take the yet-to-be determined tag IDs. status.TagIDs = make([]string, len(status.Tags)) @@ -455,7 +460,7 @@ func (d *deref) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) er return nil } -func (d *deref) fetchStatusAttachments(ctx context.Context, tsport transport.Transport, existing, status *gtsmodel.Status) error { +func (d *Dereferencer) fetchStatusAttachments(ctx context.Context, tsport transport.Transport, existing, status *gtsmodel.Status) error { // Allocate new slice to take the yet-to-be fetched attachment IDs. status.AttachmentIDs = make([]string, len(status.Attachments)) @@ -519,7 +524,7 @@ func (d *deref) fetchStatusAttachments(ctx context.Context, tsport transport.Tra return nil } -func (d *deref) fetchStatusEmojis(ctx context.Context, requestUser string, status *gtsmodel.Status) error { +func (d *Dereferencer) fetchStatusEmojis(ctx context.Context, requestUser string, status *gtsmodel.Status) error { // Fetch the full-fleshed-out emoji objects for our status. emojis, err := d.populateEmojis(ctx, status.Emojis, requestUser) if err != nil { diff --git a/internal/federation/dereferencing/thread.go b/internal/federation/dereferencing/thread.go index 6d8c913c7..5753ce4dd 100644 --- a/internal/federation/dereferencing/thread.go +++ b/internal/federation/dereferencing/thread.go @@ -38,7 +38,7 @@ import ( // ancesters we are willing to follow before returning error. const maxIter = 1000 -func (d *deref) dereferenceThread(ctx context.Context, username string, statusIRI *url.URL, status *gtsmodel.Status, statusable ap.Statusable) { +func (d *Dereferencer) dereferenceThread(ctx context.Context, username string, statusIRI *url.URL, status *gtsmodel.Status, statusable ap.Statusable) { // Ensure that ancestors have been fully dereferenced if err := d.DereferenceStatusAncestors(ctx, username, status); err != nil { log.Error(ctx, err) @@ -50,11 +50,8 @@ func (d *deref) dereferenceThread(ctx context.Context, username string, statusIR } } -func (d *deref) DereferenceStatusAncestors( - ctx context.Context, - username string, - status *gtsmodel.Status, -) error { +// DereferenceStatusAncestors iterates upwards from the given status, using InReplyToURI, to ensure that as many parent statuses as possible are dereferenced. +func (d *Dereferencer) DereferenceStatusAncestors(ctx context.Context, username string, status *gtsmodel.Status) error { // Start log entry with fields l := log.WithContext(ctx). WithFields(kv.Fields{ @@ -220,7 +217,8 @@ func (d *deref) DereferenceStatusAncestors( return gtserror.Newf("reached %d ancestor iterations for %q", maxIter, status.URI) } -func (d *deref) DereferenceStatusDescendants(ctx context.Context, username string, statusIRI *url.URL, parent ap.Statusable) error { +// DereferenceStatusDescendents iterates downwards from the given status, using its replies, to ensure that as many children statuses as possible are dereferenced. +func (d *Dereferencer) DereferenceStatusDescendants(ctx context.Context, username string, statusIRI *url.URL, parent ap.Statusable) error { statusIRIStr := statusIRI.String() // Start log entry with fields |