mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[bugfix] Fix possible race condition in federatingdb (#490)
Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
7
vendor/github.com/superseriousbusiness/activity/pub/database.go
generated
vendored
7
vendor/github.com/superseriousbusiness/activity/pub/database.go
generated
vendored
@ -19,12 +19,7 @@ type Database interface {
|
||||
// processes require tight loops acquiring and releasing locks.
|
||||
//
|
||||
// Used to ensure race conditions in multiple requests do not occur.
|
||||
Lock(c context.Context, id *url.URL) error
|
||||
// Unlock makes the lock for the object at the specified id available.
|
||||
// If an error is returned, the lock must have still been freed.
|
||||
//
|
||||
// Used to ensure race conditions in multiple requests do not occur.
|
||||
Unlock(c context.Context, id *url.URL) error
|
||||
Lock(c context.Context, id *url.URL) (unlock func(), err error)
|
||||
// InboxContains returns true if the OrderedCollection at 'inbox'
|
||||
// contains the specified 'id'.
|
||||
//
|
||||
|
76
vendor/github.com/superseriousbusiness/activity/pub/federating_wrapped_callbacks.go
generated
vendored
76
vendor/github.com/superseriousbusiness/activity/pub/federating_wrapped_callbacks.go
generated
vendored
@ -263,11 +263,12 @@ func (w FederatingWrappedCallbacks) create(c context.Context, a vocab.ActivitySt
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = w.db.Lock(c, id)
|
||||
var unlock func()
|
||||
unlock, err = w.db.Lock(c, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, id)
|
||||
defer unlock()
|
||||
if err := w.db.Create(c, t); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -304,11 +305,12 @@ func (w FederatingWrappedCallbacks) update(c context.Context, a vocab.ActivitySt
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = w.db.Lock(c, id)
|
||||
var unlock func()
|
||||
unlock, err = w.db.Lock(c, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, id)
|
||||
defer unlock()
|
||||
if err := w.db.Update(c, t); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -341,11 +343,12 @@ func (w FederatingWrappedCallbacks) deleteFn(c context.Context, a vocab.Activity
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = w.db.Lock(c, id)
|
||||
var unlock func()
|
||||
unlock, err = w.db.Lock(c, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, id)
|
||||
defer unlock()
|
||||
if err := w.db.Delete(c, id); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -373,16 +376,16 @@ func (w FederatingWrappedCallbacks) follow(c context.Context, a vocab.ActivitySt
|
||||
//
|
||||
// If not then don't send a response. It was federated to us as an FYI,
|
||||
// by mistake, or some other reason.
|
||||
if err := w.db.Lock(c, w.inboxIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, w.inboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred.
|
||||
actorIRI, err := w.db.ActorForInbox(c, w.inboxIRI)
|
||||
unlock() // unlock even on error
|
||||
if err != nil {
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
// Unlock must be called by now and every branch above.
|
||||
isMe := false
|
||||
if w.OnFollow != OnFollowDoNothing {
|
||||
@ -434,13 +437,14 @@ func (w FederatingWrappedCallbacks) follow(c context.Context, a vocab.ActivitySt
|
||||
//
|
||||
// If automatically rejecting, do not update the
|
||||
// followers collection.
|
||||
if err := w.db.Lock(c, actorIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, actorIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred.
|
||||
followers, err := w.db.Followers(c, actorIRI)
|
||||
if err != nil {
|
||||
w.db.Unlock(c, actorIRI)
|
||||
unlock()
|
||||
return err
|
||||
}
|
||||
items := followers.GetActivityStreamsItems()
|
||||
@ -451,21 +455,23 @@ func (w FederatingWrappedCallbacks) follow(c context.Context, a vocab.ActivitySt
|
||||
for _, elem := range recipients {
|
||||
items.PrependIRI(elem)
|
||||
}
|
||||
if err = w.db.Update(c, followers); err != nil {
|
||||
w.db.Unlock(c, actorIRI)
|
||||
err = w.db.Update(c, followers)
|
||||
unlock() // unlock even on error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, actorIRI)
|
||||
// Unlock must be called by now and every branch above.
|
||||
}
|
||||
// Lock without defer!
|
||||
w.db.Lock(c, w.inboxIRI)
|
||||
outboxIRI, err := w.db.OutboxForInbox(c, w.inboxIRI)
|
||||
unlock, err := w.db.Lock(c, w.inboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outboxIRI, err := w.db.OutboxForInbox(c, w.inboxIRI)
|
||||
unlock() // unlock after, regardless
|
||||
if err != nil {
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
// Everything must be unlocked by now.
|
||||
if err := w.addNewIds(c, response); err != nil {
|
||||
return err
|
||||
@ -484,16 +490,16 @@ func (w FederatingWrappedCallbacks) accept(c context.Context, a vocab.ActivitySt
|
||||
op := a.GetActivityStreamsObject()
|
||||
if op != nil && op.Len() > 0 {
|
||||
// Get this actor's id.
|
||||
if err := w.db.Lock(c, w.inboxIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, w.inboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred.
|
||||
actorIRI, err := w.db.ActorForInbox(c, w.inboxIRI)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, w.inboxIRI)
|
||||
// Unlock must be called by now and every branch above.
|
||||
//
|
||||
// Determine if we are in a follow on the 'object' property.
|
||||
@ -568,10 +574,11 @@ func (w FederatingWrappedCallbacks) accept(c context.Context, a vocab.ActivitySt
|
||||
// Use an anonymous function to properly scope the
|
||||
// database lock, immediately call it.
|
||||
err = func() error {
|
||||
if err := w.db.Lock(c, maybeMyFollowIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, maybeMyFollowIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, maybeMyFollowIRI)
|
||||
defer unlock()
|
||||
t, err := w.db.Get(c, maybeMyFollowIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -630,13 +637,14 @@ func (w FederatingWrappedCallbacks) accept(c context.Context, a vocab.ActivitySt
|
||||
return err
|
||||
}
|
||||
// Add the peer to our following collection.
|
||||
if err := w.db.Lock(c, actorIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, actorIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred.
|
||||
following, err := w.db.Following(c, actorIRI)
|
||||
if err != nil {
|
||||
w.db.Unlock(c, actorIRI)
|
||||
unlock()
|
||||
return err
|
||||
}
|
||||
items := following.GetActivityStreamsItems()
|
||||
@ -647,16 +655,16 @@ func (w FederatingWrappedCallbacks) accept(c context.Context, a vocab.ActivitySt
|
||||
for iter := activityActors.Begin(); iter != activityActors.End(); iter = iter.Next() {
|
||||
id, err := ToId(iter)
|
||||
if err != nil {
|
||||
w.db.Unlock(c, actorIRI)
|
||||
unlock()
|
||||
return err
|
||||
}
|
||||
items.PrependIRI(id)
|
||||
}
|
||||
if err = w.db.Update(c, following); err != nil {
|
||||
w.db.Unlock(c, actorIRI)
|
||||
err = w.db.Update(c, following)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, actorIRI)
|
||||
// Unlock must be called by now and every branch above.
|
||||
}
|
||||
}
|
||||
@ -729,10 +737,11 @@ func (w FederatingWrappedCallbacks) like(c context.Context, a vocab.ActivityStre
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.db.Lock(c, objId); err != nil {
|
||||
unlock, err := w.db.Lock(c, objId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, objId)
|
||||
defer unlock()
|
||||
if owns, err := w.db.Owns(c, objId); err != nil {
|
||||
return err
|
||||
} else if !owns {
|
||||
@ -810,10 +819,11 @@ func (w FederatingWrappedCallbacks) announce(c context.Context, a vocab.Activity
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.db.Lock(c, objId); err != nil {
|
||||
unlock, err := w.db.Lock(c, objId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, objId)
|
||||
defer unlock()
|
||||
if owns, err := w.db.Owns(c, objId); err != nil {
|
||||
return err
|
||||
} else if !owns {
|
||||
|
8
vendor/github.com/superseriousbusiness/activity/pub/handlers.go
generated
vendored
8
vendor/github.com/superseriousbusiness/activity/pub/handlers.go
generated
vendored
@ -64,18 +64,20 @@ func NewActivityStreamsHandlerScheme(db Database, clock Clock, scheme string) Ha
|
||||
}
|
||||
isASRequest = true
|
||||
id := requestId(r, scheme)
|
||||
|
||||
var unlock func()
|
||||
|
||||
// Lock and obtain a copy of the requested ActivityStreams value
|
||||
err = db.Lock(c, id)
|
||||
unlock, err = db.Lock(c, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// WARNING: Unlock not deferred
|
||||
t, err := db.Get(c, id)
|
||||
unlock() // unlock even on error
|
||||
if err != nil {
|
||||
db.Unlock(c, id)
|
||||
return
|
||||
}
|
||||
db.Unlock(c, id)
|
||||
// Unlock must have been called by this point and in every
|
||||
// branch above
|
||||
if t == nil {
|
||||
|
93
vendor/github.com/superseriousbusiness/activity/pub/side_effect_actor.go
generated
vendored
93
vendor/github.com/superseriousbusiness/activity/pub/side_effect_actor.go
generated
vendored
@ -148,7 +148,7 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
||||
// Obtain the id of the activity
|
||||
id := activity.GetJSONLDId()
|
||||
// Acquire a lock for the id. To be held for the rest of execution.
|
||||
err := a.db.Lock(c, id.Get())
|
||||
unlock, err := a.db.Lock(c, id.Get())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -157,19 +157,18 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
||||
// If the database already contains the activity, exit early.
|
||||
exists, err := a.db.Exists(c, id.Get())
|
||||
if err != nil {
|
||||
a.db.Unlock(c, id.Get())
|
||||
unlock()
|
||||
return err
|
||||
} else if exists {
|
||||
a.db.Unlock(c, id.Get())
|
||||
unlock()
|
||||
return nil
|
||||
}
|
||||
// Attempt to create the activity entry.
|
||||
err = a.db.Create(c, activity)
|
||||
unlock() // unlock even on error return
|
||||
if err != nil {
|
||||
a.db.Unlock(c, id.Get())
|
||||
return err
|
||||
}
|
||||
a.db.Unlock(c, id.Get())
|
||||
// Unlock by this point and in every branch above.
|
||||
//
|
||||
// 2. The values of 'to', 'cc', or 'audience' are Collections owned by
|
||||
@ -212,19 +211,19 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.db.Lock(c, iri)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, iri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock is not deferred
|
||||
if owns, err := a.db.Owns(c, iri); err != nil {
|
||||
a.db.Unlock(c, iri)
|
||||
owns, err := a.db.Owns(c, iri)
|
||||
unlock() // unlock even on error
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !owns {
|
||||
a.db.Unlock(c, iri)
|
||||
continue
|
||||
}
|
||||
a.db.Unlock(c, iri)
|
||||
// Unlock by this point and in every branch above.
|
||||
myIRIs = append(myIRIs, iri)
|
||||
}
|
||||
@ -236,7 +235,8 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
||||
col := make(map[string]itemser)
|
||||
oCol := make(map[string]orderedItemser)
|
||||
for _, iri := range myIRIs {
|
||||
err = a.db.Lock(c, iri)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, iri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -249,20 +249,20 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
||||
if im, ok := t.(orderedItemser); ok {
|
||||
oCol[iri.String()] = im
|
||||
colIRIs = append(colIRIs, iri)
|
||||
defer a.db.Unlock(c, iri)
|
||||
defer unlock()
|
||||
} else {
|
||||
a.db.Unlock(c, iri)
|
||||
unlock() // unlock instantly
|
||||
}
|
||||
} else if streams.IsOrExtendsActivityStreamsCollection(t) {
|
||||
if im, ok := t.(itemser); ok {
|
||||
col[iri.String()] = im
|
||||
colIRIs = append(colIRIs, iri)
|
||||
defer a.db.Unlock(c, iri)
|
||||
defer unlock()
|
||||
} else {
|
||||
a.db.Unlock(c, iri)
|
||||
unlock() // unlock instantly
|
||||
}
|
||||
} else {
|
||||
a.db.Unlock(c, iri)
|
||||
unlock() // unlock instantly
|
||||
}
|
||||
}
|
||||
// If we own none of the Collection IRIs in 'to', 'cc', or 'audience'
|
||||
@ -409,17 +409,17 @@ func (a *sideEffectActor) Deliver(c context.Context, outboxIRI *url.URL, activit
|
||||
|
||||
// WrapInCreate wraps an object with a Create activity.
|
||||
func (a *sideEffectActor) WrapInCreate(c context.Context, obj vocab.Type, outboxIRI *url.URL) (create vocab.ActivityStreamsCreate, err error) {
|
||||
err = a.db.Lock(c, outboxIRI)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, outboxIRI)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// WARNING: No deferring the Unlock
|
||||
actorIRI, err := a.db.ActorForOutbox(c, outboxIRI)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
a.db.Unlock(c, outboxIRI)
|
||||
return
|
||||
}
|
||||
a.db.Unlock(c, outboxIRI)
|
||||
// Unlock the lock at this point and every branch above
|
||||
return wrapInCreate(c, obj, actorIRI)
|
||||
}
|
||||
@ -447,26 +447,25 @@ func (a *sideEffectActor) deliverToRecipients(c context.Context, boxIRI *url.URL
|
||||
func (a *sideEffectActor) addToOutbox(c context.Context, outboxIRI *url.URL, activity Activity) error {
|
||||
// Set the activity in the database first.
|
||||
id := activity.GetJSONLDId()
|
||||
err := a.db.Lock(c, id.Get())
|
||||
unlock, err := a.db.Lock(c, id.Get())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred
|
||||
err = a.db.Create(c, activity)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
a.db.Unlock(c, id.Get())
|
||||
return err
|
||||
}
|
||||
a.db.Unlock(c, id.Get())
|
||||
// WARNING: Unlock(c, id) should be called by this point and in every
|
||||
// return before here.
|
||||
//
|
||||
// Acquire a lock to read the outbox. Defer release.
|
||||
err = a.db.Lock(c, outboxIRI)
|
||||
unlock, err = a.db.Lock(c, outboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer a.db.Unlock(c, outboxIRI)
|
||||
defer unlock()
|
||||
outbox, err := a.db.GetOutbox(c, outboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -491,11 +490,12 @@ func (a *sideEffectActor) addToOutbox(c context.Context, outboxIRI *url.URL, act
|
||||
// Returns true when the activity is novel.
|
||||
func (a *sideEffectActor) addToInboxIfNew(c context.Context, inboxIRI *url.URL, activity Activity) (isNew bool, err error) {
|
||||
// Acquire a lock to read the inbox. Defer release.
|
||||
err = a.db.Lock(c, inboxIRI)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, inboxIRI)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer a.db.Unlock(c, inboxIRI)
|
||||
defer unlock()
|
||||
// Obtain the id of the activity
|
||||
id := activity.GetJSONLDId()
|
||||
// If the inbox already contains the URL, early exit.
|
||||
@ -539,19 +539,18 @@ func (a *sideEffectActor) hasInboxForwardingValues(c context.Context, inboxIRI *
|
||||
types, iris := getInboxForwardingValues(val)
|
||||
// For IRIs, simply check if we own them.
|
||||
for _, iri := range iris {
|
||||
err := a.db.Lock(c, iri)
|
||||
unlock, err := a.db.Lock(c, iri)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// WARNING: Unlock is not deferred
|
||||
if owns, err := a.db.Owns(c, iri); err != nil {
|
||||
a.db.Unlock(c, iri)
|
||||
owns, err := a.db.Owns(c, iri)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if owns {
|
||||
a.db.Unlock(c, iri)
|
||||
return true, nil
|
||||
}
|
||||
a.db.Unlock(c, iri)
|
||||
// Unlock by this point and in every branch above
|
||||
}
|
||||
// For embedded literals, check the id.
|
||||
@ -560,19 +559,19 @@ func (a *sideEffectActor) hasInboxForwardingValues(c context.Context, inboxIRI *
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
err = a.db.Lock(c, id)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// WARNING: Unlock is not deferred
|
||||
if owns, err := a.db.Owns(c, id); err != nil {
|
||||
a.db.Unlock(c, id)
|
||||
owns, err := a.db.Owns(c, id)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if owns {
|
||||
a.db.Unlock(c, id)
|
||||
return true, nil
|
||||
}
|
||||
a.db.Unlock(c, id)
|
||||
// Unlock by this point and in every branch above
|
||||
}
|
||||
// Recur Preparation: Try fetching the IRIs so we can recur into them.
|
||||
@ -683,7 +682,8 @@ func (a *sideEffectActor) prepare(c context.Context, outboxIRI *url.URL, activit
|
||||
foundInboxesFromDB := []*url.URL{}
|
||||
for _, actorIRI := range r {
|
||||
// BEGIN LOCK
|
||||
err = a.db.Lock(c, actorIRI)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, actorIRI)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -691,7 +691,7 @@ func (a *sideEffectActor) prepare(c context.Context, outboxIRI *url.URL, activit
|
||||
inboxes, err := a.db.InboxesForIRI(c, actorIRI)
|
||||
if err != nil {
|
||||
// bail on error
|
||||
a.db.Unlock(c, actorIRI)
|
||||
unlock()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -699,16 +699,13 @@ func (a *sideEffectActor) prepare(c context.Context, outboxIRI *url.URL, activit
|
||||
// we have a hit
|
||||
foundInboxesFromDB = append(foundInboxesFromDB, inboxes...)
|
||||
|
||||
// if we found inboxes for this iri, we should remove it from
|
||||
// if we found inboxes for this iri, we should remove it from
|
||||
// the list of actors/iris we still need to dereference
|
||||
r = removeOne(r, actorIRI)
|
||||
}
|
||||
|
||||
// END LOCK
|
||||
a.db.Unlock(c, actorIRI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unlock()
|
||||
}
|
||||
|
||||
// look for any actors' inboxes that weren't already discovered above;
|
||||
@ -733,25 +730,25 @@ func (a *sideEffectActor) prepare(c context.Context, outboxIRI *url.URL, activit
|
||||
targets = append(targets, foundInboxesFromRemote...)
|
||||
|
||||
// Get inboxes of sender.
|
||||
err = a.db.Lock(c, outboxIRI)
|
||||
var unlock func()
|
||||
unlock, err = a.db.Lock(c, outboxIRI)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// WARNING: No deferring the Unlock
|
||||
actorIRI, err := a.db.ActorForOutbox(c, outboxIRI)
|
||||
unlock() // unlock after regardless
|
||||
if err != nil {
|
||||
a.db.Unlock(c, outboxIRI)
|
||||
return
|
||||
}
|
||||
a.db.Unlock(c, outboxIRI)
|
||||
// Get the inbox on the sender.
|
||||
err = a.db.Lock(c, actorIRI)
|
||||
unlock, err = a.db.Lock(c, actorIRI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// BEGIN LOCK
|
||||
thisActor, err := a.db.Get(c, actorIRI)
|
||||
a.db.Unlock(c, actorIRI)
|
||||
unlock()
|
||||
// END LOCK -- Still need to handle err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
24
vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go
generated
vendored
24
vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go
generated
vendored
@ -259,11 +259,12 @@ func (w SocialWrappedCallbacks) create(c context.Context, a vocab.ActivityStream
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = w.db.Lock(c, id)
|
||||
var unlock func()
|
||||
unlock, err = w.db.Lock(c, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, id)
|
||||
defer unlock()
|
||||
if err := w.db.Create(c, obj); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -301,11 +302,11 @@ func (w SocialWrappedCallbacks) update(c context.Context, a vocab.ActivityStream
|
||||
// Create anonymous loop function to be able to properly scope the defer
|
||||
// for the database lock at each iteration.
|
||||
loopFn := func(idx int, loopId *url.URL) error {
|
||||
err := w.db.Lock(c, loopId)
|
||||
unlock, err := w.db.Lock(c, loopId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, loopId)
|
||||
defer unlock()
|
||||
t, err := w.db.Get(c, loopId)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -371,11 +372,11 @@ func (w SocialWrappedCallbacks) deleteFn(c context.Context, a vocab.ActivityStre
|
||||
// Create anonymous loop function to be able to properly scope the defer
|
||||
// for the database lock at each iteration.
|
||||
loopFn := func(idx int, loopId *url.URL) error {
|
||||
err := w.db.Lock(c, loopId)
|
||||
unlock, err := w.db.Lock(c, loopId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, loopId)
|
||||
defer unlock()
|
||||
t, err := w.db.Get(c, loopId)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -458,23 +459,24 @@ func (w SocialWrappedCallbacks) like(c context.Context, a vocab.ActivityStreamsL
|
||||
return ErrObjectRequired
|
||||
}
|
||||
// Get this actor's IRI.
|
||||
if err := w.db.Lock(c, w.outboxIRI); err != nil {
|
||||
unlock, err := w.db.Lock(c, w.outboxIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// WARNING: Unlock not deferred.
|
||||
actorIRI, err := w.db.ActorForOutbox(c, w.outboxIRI)
|
||||
unlock() // unlock even on error
|
||||
if err != nil {
|
||||
w.db.Unlock(c, w.outboxIRI)
|
||||
return err
|
||||
}
|
||||
w.db.Unlock(c, w.outboxIRI)
|
||||
// Unlock must be called by now and every branch above.
|
||||
//
|
||||
// Now obtain this actor's 'liked' collection.
|
||||
if err := w.db.Lock(c, actorIRI); err != nil {
|
||||
unlock, err = w.db.Lock(c, actorIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.db.Unlock(c, actorIRI)
|
||||
defer unlock()
|
||||
liked, err := w.db.Liked(c, actorIRI)
|
||||
if err != nil {
|
||||
return err
|
||||
|
19
vendor/github.com/superseriousbusiness/activity/pub/util.go
generated
vendored
19
vendor/github.com/superseriousbusiness/activity/pub/util.go
generated
vendored
@ -753,7 +753,8 @@ func mustHaveActivityActorsMatchObjectActors(c context.Context,
|
||||
actors vocab.ActivityStreamsActorProperty,
|
||||
op vocab.ActivityStreamsObjectProperty,
|
||||
newTransport func(c context.Context, actorBoxIRI *url.URL, gofedAgent string) (t Transport, err error),
|
||||
boxIRI *url.URL) error {
|
||||
boxIRI *url.URL,
|
||||
) error {
|
||||
activityActorMap := make(map[string]bool, actors.Len())
|
||||
for iter := actors.Begin(); iter != actors.End(); iter = iter.Next() {
|
||||
id, err := ToId(iter)
|
||||
@ -808,7 +809,8 @@ func mustHaveActivityActorsMatchObjectActors(c context.Context,
|
||||
func add(c context.Context,
|
||||
op vocab.ActivityStreamsObjectProperty,
|
||||
target vocab.ActivityStreamsTargetProperty,
|
||||
db Database) error {
|
||||
db Database,
|
||||
) error {
|
||||
opIds := make([]*url.URL, 0, op.Len())
|
||||
for iter := op.Begin(); iter != op.End(); iter = iter.Next() {
|
||||
id, err := ToId(iter)
|
||||
@ -828,10 +830,11 @@ func add(c context.Context,
|
||||
// Create anonymous loop function to be able to properly scope the defer
|
||||
// for the database lock at each iteration.
|
||||
loopFn := func(t *url.URL) error {
|
||||
if err := db.Lock(c, t); err != nil {
|
||||
unlock, err := db.Lock(c, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Unlock(c, t)
|
||||
defer unlock()
|
||||
if owns, err := db.Owns(c, t); err != nil {
|
||||
return err
|
||||
} else if !owns {
|
||||
@ -889,7 +892,8 @@ func add(c context.Context,
|
||||
func remove(c context.Context,
|
||||
op vocab.ActivityStreamsObjectProperty,
|
||||
target vocab.ActivityStreamsTargetProperty,
|
||||
db Database) error {
|
||||
db Database,
|
||||
) error {
|
||||
opIds := make(map[string]bool, op.Len())
|
||||
for iter := op.Begin(); iter != op.End(); iter = iter.Next() {
|
||||
id, err := ToId(iter)
|
||||
@ -909,10 +913,11 @@ func remove(c context.Context,
|
||||
// Create anonymous loop function to be able to properly scope the defer
|
||||
// for the database lock at each iteration.
|
||||
loopFn := func(t *url.URL) error {
|
||||
if err := db.Lock(c, t); err != nil {
|
||||
unlock, err := db.Lock(c, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Unlock(c, t)
|
||||
defer unlock()
|
||||
if owns, err := db.Owns(c, t); err != nil {
|
||||
return err
|
||||
} else if !owns {
|
||||
|
Reference in New Issue
Block a user