demo/showoff.md
!SLIDE
# Mongoid-Locker
[github.com/afeld/mongoid-locker](https://github.com/afeld/mongoid-locker)
## Aidan Feldman, [Jux.com](https://jux.com)
!SLIDE
![Instagram diagram](instagram.png)
!SLIDE
# Jux needed a queue.
* Distributed, but synchronized
* No add'l DB
* No add'l hassle (managing workers, etc.)
!SLIDE
* Thread
- \+ Distributed
- – Not synchronized
* Many workers
- \+ Distributed
- – Not synchronized
* One worker
- \+ Synchronized
- – Not distributed
- – Single POF
!SLIDE
@@@ ruby
require 'rubygems'
require 'mongoid-locker'
Mongoid.load!('config/mongoid.yml', :development)
class User
include Mongoid::Document
# include Mongoid::Locker
field :balance, type: Float
end
# cleanup
User.destroy_all
bob = User.create!(balance: 100.00)
!SLIDE
# Atomic Operations
@@@ ruby
class User
def purchase(amount)
if amount > self.balance
raise "Can't have negative balance!"
else
# deduct *atomically*
self.inc(:balance, -1 * amount)
# a.k.a.
# db.users.update({_id: ...}, {$inc: {balance: ...}})
puts "cha-ching!"
end
end
end
bob.purchase(5.10) #=> "cha-ching!"
bob.purchase(110.53) #=> "Can't have negative balance!"
!SLIDE
# All fine, right?
!SLIDE
@@@ ruby
class User
def purchase(amount)
if amount > self.balance
raise "Can't have negative balance!"
else
# artificial delay
print 'has enough money...waiting for ENTER > '
gets
self.inc(:balance, -1 * amount)
puts "cha-ching!"
end
end
end
!SLIDE
@@@ ruby
# shell 1
bob.purchase(10.00)
# shell 2
also_bob = User.first
also_bob.purchase(95.00)
!SLIDE
# oops.
!SLIDE
@@@ ruby
class User
# add doc-level locking
include Mongoid::Locker
timeout_lock_after 20
def purchase(amount)
# only one at a time
self.with_lock(wait: true) do
# after the `wait`, will have updated `balance`
if amount > self.balance
raise "Can't have negative balance!"
else
print 'has enough money...waiting for ENTER > '
gets
self.inc(:balance, -1 * amount)
puts "cha-ching!"
end
end
end
end
!SLIDE
# Summary
* Easy document-level locking
* Useful for queueing or pseudo-transactions
* No additional dependencies
!SLIDE
# Fin.
[afeld/mongoid-locker](https://github.com/afeld/mongoid-locker)
----------------
## Aidan Feldman, [Jux.com](https://jux.com)
[@aidanfeldman](https://twitter.com/aidanfeldman)
[afeld.me](http://afeld.me)