Skip to content

Commit 98eb41d

Browse files
authored
Fix race condition when deleting labels (#4944)
Concurrent requests updating the same resource's labels could fail with Sequel::NoExistingObject when both try to delete the same label. This occurred because find().destroy loads the model first, then deletes by ID - if another request deletes it in between, the delete affects 0 rows and Sequel raises an error. Changed to use where().destroy which deletes directly via SQL without loading the model, making it atomic and idempotent. Also removed unnecessary .try(:destroy) from annotations_update since where() always returns a dataset, never nil. Observed error: CF-NoExistingObject: Attempt to delete object did not result in a single row modification (Rows Deleted: 0, SQL: DELETE FROM "service_instance_labels" WHERE ("id" = ...))
1 parent 63a5a5b commit 98eb41d

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

app/actions/annotations_update.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def update(resource, annotations, annotation_klass, destroy_nil: true)
1010
prefix, key_name = VCAP::CloudController::MetadataHelpers.extract_prefix(key)
1111

1212
if value.nil? && destroy_nil # Delete Annotation
13-
annotation_klass.where(resource_guid: resource.guid, key_name: key_name).where(Sequel.or([[:key_prefix, prefix], [:key_prefix, prefix.to_s]])).try(:destroy)
13+
annotation_klass.where(resource_guid: resource.guid, key_name: key_name).where(Sequel.or([[:key_prefix, prefix], [:key_prefix, prefix.to_s]])).destroy
1414
next
1515
end
1616

app/actions/labels_update.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def update(resource, labels, label_klass, destroy_nil: true)
1212
prefix, name = VCAP::CloudController::MetadataHelpers.extract_prefix(label_key)
1313

1414
if label_value.nil? && destroy_nil # Delete Label
15-
label_klass.find(key_prefix: prefix.to_s, resource_guid: resource.guid, key_name: name)&.destroy
15+
label_klass.where(key_prefix: prefix.to_s, resource_guid: resource.guid, key_name: name).destroy
1616
next
1717
end
1818

0 commit comments

Comments
 (0)