Atomic Operations
NoBrainer supports atomic operations on document attributes to avoid races
during updates (e.g. incrementing a number).
NoBrainer provides a natural Ruby syntax to describe atomic
operations: assignments ran within a queue_atomic block are performed
atomically during the next save() operation.
Examples
The following examples use the following base code:
class User
field :num_friends, :type => Integer
field :friend_ids, :type => Array
field :tags, :type => Set
field :field1
field :field2
end
user = User.firstIncrementing a field
user.queue_atomic do
user.num_friends += 1
end
user.save!Removing items from an array
user.queue_atomic do
user.friend_ids -= ["id1", "id2"]
end
user.save!Adding items to a set
user.queue_atomic do
user.tags << "red"
end
user.save!Swapping two fields
user.queue_atomic do
user.field1, user.field2 = user.field2, user.field1
end
user.save!Using different fields to compute some value
user.queue_atomic do
user.field2 = (user.num_friends + user.field1)*2
end
user.save!Removing a field
user.queue_atomic do
user.unset(:field1)
end
user.save!Using a RQL value
user.queue_atomic do |r|
user.field1 = r.expr(1+2)
end
user.save!Operations
- Atomic operations are performed when invoking
save(). - Multiple atomic operations can be queued.
- Once an attribute has atomic operations queued, validations are no longer performed on that attribute.
- Once an atomic value is queued, the attribute value cannot be read anymore.
The following describes operations that can be performed on various types:
Any types
instance.unset(:field)removes the specified field from the document.instance.field = valueassignsfieldtovalue, which can be a RQL expression, or some operation using other fields from the same document.
Array
values1 & values2performs the set intersection betweenvalues1andvalues2.values1 | values2performs the set union ofvalues1andvalues2.values1 + values2performs the concatenation ofvalues1andvalues2.values1 - values2performs the difference betweenvalues1andvalues2.values << valueappendsvaluetovalues.values.delete(value)removesvaluefromvalues.
Set
Same as Array, except all operations are done with Set semantics.
String
value1 + value2performs the concatenation of the two strings.
Integer / Float
+ - / %performs the usual numeric computations.