mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 14:42:26 -05:00 
			
		
		
		
	[feature] support canceling scheduled tasks, some federation API performance improvements (#2329)
This commit is contained in:
		
					parent
					
						
							
								314dda196e
							
						
					
				
			
			
				commit
				
					
						41435a6c4e
					
				
			
		
					 23 changed files with 993 additions and 487 deletions
				
			
		|  | @ -32,6 +32,7 @@ import ( | |||
| 	"github.com/superseriousbusiness/gotosocial/internal/messages" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/processing/account" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/state" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||
| ) | ||||
| 
 | ||||
| // fediAPI wraps processing functions | ||||
|  | @ -142,27 +143,22 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg messages.FromFe | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| 	return gtserror.Newf("unhandled: %s %s", fMsg.APActivityType, fMsg.APObjectType) | ||||
| } | ||||
| 
 | ||||
| func (p *fediAPI) CreateStatus(ctx context.Context, fMsg messages.FromFediAPI) error { | ||||
| 	var ( | ||||
| 		status *gtsmodel.Status | ||||
| 		err    error | ||||
| 
 | ||||
| 		// Check the federatorMsg for either an already dereferenced | ||||
| 		// and converted status pinned to the message, or a forwarded | ||||
| 		// AP IRI that we still need to deref. | ||||
| 		forwarded = (fMsg.GTSModel == nil) | ||||
| 	) | ||||
| 
 | ||||
| 	if forwarded { | ||||
| 		// Model was not set, deref with IRI. | ||||
| 	if fMsg.APObjectModel == nil /* i.e. forwarded */ { | ||||
| 		// Model was not set, deref with IRI (this is a forward). | ||||
| 		// This will also cause the status to be inserted into the db. | ||||
| 		status, err = p.statusFromAPIRI(ctx, fMsg) | ||||
| 	} else { | ||||
| 		// Model is set, ensure we have the most up-to-date model. | ||||
| 		status, err = p.statusFromGTSModel(ctx, fMsg) | ||||
| 		status, err = p.statusFromAPModel(ctx, fMsg) | ||||
| 	} | ||||
| 
 | ||||
| 	if err != nil { | ||||
|  | @ -188,19 +184,10 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg messages.FromFediAPI) e | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Ensure status ancestors dereferenced. We need at least the | ||||
| 	// immediate parent (if present) to ascertain timelineability. | ||||
| 	if err := p.federate.DereferenceStatusAncestors( | ||||
| 		ctx, | ||||
| 		fMsg.ReceivingAccount.Username, | ||||
| 		status, | ||||
| 	); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if status.InReplyToID != "" { | ||||
| 		// Interaction counts changed on the replied status; | ||||
| 		// uncache the prepared version from all timelines. | ||||
| 		// Interaction counts changed on the replied status; uncache the | ||||
| 		// prepared version from all timelines. The status dereferencer | ||||
| 		// functions will ensure necessary ancestors exist before this point. | ||||
| 		p.surface.invalidateStatusFromTimelines(ctx, status.InReplyToID) | ||||
| 	} | ||||
| 
 | ||||
|  | @ -211,23 +198,31 @@ func (p *fediAPI) CreateStatus(ctx context.Context, fMsg messages.FromFediAPI) e | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *fediAPI) statusFromGTSModel(ctx context.Context, fMsg messages.FromFediAPI) (*gtsmodel.Status, error) { | ||||
| 	// There should be a status pinned to the message: | ||||
| 	// we've already checked to ensure this is not nil. | ||||
| 	status, ok := fMsg.GTSModel.(*gtsmodel.Status) | ||||
| func (p *fediAPI) statusFromAPModel(ctx context.Context, fMsg messages.FromFediAPI) (*gtsmodel.Status, error) { | ||||
| 	// AP statusable representation MUST have been set. | ||||
| 	statusable, ok := fMsg.APObjectModel.(ap.Statusable) | ||||
| 	if !ok { | ||||
| 		err := gtserror.New("Note was not parseable as *gtsmodel.Status") | ||||
| 		return nil, err | ||||
| 		return nil, gtserror.Newf("cannot cast %T -> ap.Statusable", fMsg.APObjectModel) | ||||
| 	} | ||||
| 
 | ||||
| 	// AP statusable representation may have also | ||||
| 	// been set on message (no problem if not). | ||||
| 	statusable, _ := fMsg.APObjectModel.(ap.Statusable) | ||||
| 	// Status may have been set (no problem if not). | ||||
| 	status, _ := fMsg.GTSModel.(*gtsmodel.Status) | ||||
| 
 | ||||
| 	// Call refresh on status to update | ||||
| 	// it (deref remote) if necessary. | ||||
| 	var err error | ||||
| 	status, _, err = p.federate.RefreshStatus( | ||||
| 	if status == nil { | ||||
| 		// No status was set, create a bare-bones | ||||
| 		// model for the deferencer to flesh-out, | ||||
| 		// this indicates it is a new (to us) status. | ||||
| 		status = >smodel.Status{ | ||||
| 
 | ||||
| 			// if coming in here status will ALWAYS be remote. | ||||
| 			Local: util.Ptr(false), | ||||
| 			URI:   ap.GetJSONLDId(statusable).String(), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Call refresh on status to either update existing | ||||
| 	// model, or parse + insert status from statusable data. | ||||
| 	status, _, err := p.federate.RefreshStatus( | ||||
| 		ctx, | ||||
| 		fMsg.ReceivingAccount.Username, | ||||
| 		status, | ||||
|  | @ -235,7 +230,7 @@ func (p *fediAPI) statusFromGTSModel(ctx context.Context, fMsg messages.FromFedi | |||
| 		false, // Don't force refresh. | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, gtserror.Newf("%w", err) | ||||
| 		return nil, gtserror.Newf("error refreshing status: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return status, nil | ||||
|  | @ -245,11 +240,8 @@ func (p *fediAPI) statusFromAPIRI(ctx context.Context, fMsg messages.FromFediAPI | |||
| 	// There should be a status IRI pinned to | ||||
| 	// the federatorMsg for us to dereference. | ||||
| 	if fMsg.APIri == nil { | ||||
| 		err := gtserror.New( | ||||
| 			"status was not pinned to federatorMsg, " + | ||||
| 				"and neither was an IRI for us to dereference", | ||||
| 		) | ||||
| 		return nil, err | ||||
| 		const text = "neither APObjectModel nor APIri set" | ||||
| 		return nil, gtserror.New(text) | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the status + ensure we have | ||||
|  | @ -260,7 +252,7 @@ func (p *fediAPI) statusFromAPIRI(ctx context.Context, fMsg messages.FromFediAPI | |||
| 		fMsg.APIri, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, gtserror.Newf("%w", err) | ||||
| 		return nil, gtserror.Newf("error getting status by uri %s: %w", fMsg.APIri, err) | ||||
| 	} | ||||
| 
 | ||||
| 	return status, nil | ||||
|  | @ -337,7 +329,9 @@ func (p *fediAPI) CreateAnnounce(ctx context.Context, fMsg messages.FromFediAPI) | |||
| 		return gtserror.Newf("%T not parseable as *gtsmodel.Status", fMsg.GTSModel) | ||||
| 	} | ||||
| 
 | ||||
| 	// Dereference status that this status boosts. | ||||
| 	// Dereference status that this boosts, note | ||||
| 	// that this will handle dereferencing the status | ||||
| 	// ancestors / descendants where appropriate. | ||||
| 	if err := p.federate.DereferenceAnnounce( | ||||
| 		ctx, | ||||
| 		status, | ||||
|  | @ -358,15 +352,6 @@ func (p *fediAPI) CreateAnnounce(ctx context.Context, fMsg messages.FromFediAPI) | |||
| 		return gtserror.Newf("db error inserting status: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Ensure boosted status ancestors dereferenced. We need at least | ||||
| 	// the immediate parent (if present) to ascertain timelineability. | ||||
| 	if err := p.federate.DereferenceStatusAncestors(ctx, | ||||
| 		fMsg.ReceivingAccount.Username, | ||||
| 		status.BoostOf, | ||||
| 	); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Timeline and notify the announce. | ||||
| 	if err := p.surface.timelineAndNotifyStatus(ctx, status); err != nil { | ||||
| 		return gtserror.Newf("error timelining status: %w", err) | ||||
|  | @ -526,23 +511,25 @@ func (p *fediAPI) UpdateStatus(ctx context.Context, fMsg messages.FromFediAPI) e | |||
| 	} | ||||
| 
 | ||||
| 	// Cast the updated ActivityPub statusable object . | ||||
| 	apStatus, ok := fMsg.APObjectModel.(ap.Statusable) | ||||
| 	if !ok { | ||||
| 		return gtserror.Newf("cannot cast %T -> ap.Statusable", fMsg.APObjectModel) | ||||
| 	} | ||||
| 	apStatus, _ := fMsg.APObjectModel.(ap.Statusable) | ||||
| 
 | ||||
| 	// Fetch up-to-date attach status attachments, etc. | ||||
| 	_, _, err := p.federate.RefreshStatus( | ||||
| 	_, statusable, err := p.federate.RefreshStatus( | ||||
| 		ctx, | ||||
| 		fMsg.ReceivingAccount.Username, | ||||
| 		existing, | ||||
| 		apStatus, | ||||
| 		false, | ||||
| 		true, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return gtserror.Newf("error refreshing updated status: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if statusable != nil { | ||||
| 		// Status representation was refetched, uncache from timelines. | ||||
| 		p.surface.invalidateStatusFromTimelines(ctx, existing.ID) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue