mongoid-locker 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Binary file
@@ -1,16 +0,0 @@
1
- #preso,
2
- .slide {
3
- position: absolute;
4
- top: 0;
5
- left: 0;
6
- right: 0;
7
- bottom: 0;
8
- width: auto;
9
- height: auto;
10
- overflow: auto;
11
- }
12
-
13
- pre.sh_sourceCode {
14
- font-size: 2.5em;
15
- line-height: 1.2;
16
- }
@@ -1,159 +0,0 @@
1
- !SLIDE
2
-
3
- # Mongoid-Locker
4
-
5
- [github.com/mongoid/mongoid-locker](https://github.com/mongoid/mongoid-locker)
6
-
7
- ## Aidan Feldman, [Jux.com](https://jux.com)
8
-
9
- !SLIDE
10
-
11
- ![Instagram diagram](instagram.png)
12
-
13
- !SLIDE
14
-
15
- # Jux needed a queue.
16
-
17
- * Distributed, but synchronized
18
- * No add'l DB
19
- * No add'l hassle (managing workers, etc.)
20
-
21
- !SLIDE
22
-
23
- * Thread
24
- - \+ Distributed
25
- - – Not synchronized
26
- * Many workers
27
- - \+ Distributed
28
- - – Not synchronized
29
- * One worker
30
- - \+ Synchronized
31
- - – Not distributed
32
- - – Single POF
33
-
34
- !SLIDE
35
-
36
- @@@ ruby
37
- require 'rubygems'
38
- require 'mongoid-locker'
39
- Mongoid.load!('config/mongoid.yml', :development)
40
-
41
-
42
- class User
43
- include Mongoid::Document
44
- # include Mongoid::Locker
45
-
46
- field :balance, type: Float
47
- end
48
-
49
- # cleanup
50
- User.destroy_all
51
-
52
- bob = User.create!(balance: 100.00)
53
-
54
- !SLIDE
55
-
56
- # Atomic Operations
57
-
58
- @@@ ruby
59
- class User
60
- def purchase(amount)
61
- if amount > self.balance
62
- raise "Can't have negative balance!"
63
- else
64
- # deduct *atomically*
65
- self.inc(:balance, -1 * amount)
66
- # a.k.a.
67
- # db.users.update({_id: ...}, {$inc: {balance: ...}})
68
-
69
- puts "cha-ching!"
70
- end
71
- end
72
- end
73
-
74
- bob.purchase(5.10) #=> "cha-ching!"
75
- bob.purchase(110.53) #=> "Can't have negative balance!"
76
-
77
- !SLIDE
78
-
79
- # All fine, right?
80
-
81
- !SLIDE
82
-
83
- @@@ ruby
84
- class User
85
- def purchase(amount)
86
- if amount > self.balance
87
- raise "Can't have negative balance!"
88
- else
89
- # artificial delay
90
- print 'has enough money...waiting for ENTER > '
91
- gets
92
-
93
- self.inc(:balance, -1 * amount)
94
- puts "cha-ching!"
95
- end
96
- end
97
- end
98
-
99
- !SLIDE
100
-
101
- @@@ ruby
102
- # shell 1
103
- bob.purchase(10.00)
104
-
105
- # shell 2
106
- also_bob = User.first
107
- also_bob.purchase(95.00)
108
-
109
- !SLIDE
110
-
111
- # oops.
112
-
113
- !SLIDE
114
-
115
- @@@ ruby
116
- class User
117
- # add doc-level locking
118
- include Mongoid::Locker
119
- timeout_lock_after 20
120
-
121
- def purchase(amount)
122
- # only one at a time
123
- self.with_lock(wait: true) do
124
- # after the `wait`, will have updated `balance`
125
-
126
- if amount > self.balance
127
- raise "Can't have negative balance!"
128
- else
129
- print 'has enough money...waiting for ENTER > '
130
- gets
131
-
132
- self.inc(:balance, -1 * amount)
133
- puts "cha-ching!"
134
- end
135
- end
136
- end
137
- end
138
-
139
- !SLIDE
140
-
141
- # Summary
142
-
143
- * Easy document-level locking
144
- * Useful for queueing or pseudo-transactions
145
- * No additional dependencies
146
-
147
- !SLIDE
148
-
149
- # Fin.
150
-
151
- [mongoid/mongoid-locker](https://github.com/mongoid/mongoid-locker)
152
-
153
- ----------------
154
-
155
- ## Aidan Feldman
156
-
157
- [@aidanfeldman](https://twitter.com/aidanfeldman)
158
-
159
- [afeld.me](http://afeld.me)
@@ -1,26 +0,0 @@
1
- module Mongoid
2
- module Locker
3
- # Normalizes queries between various Mongoid versions.
4
- module Wrapper
5
- # Update the document for the provided Class matching the provided query with the provided setter.
6
- #
7
- # @param [Class] The model class
8
- # @param [Hash] The Mongoid query
9
- # @param [Hash] The Mongoid setter
10
- # @return [Boolean] true if the document was successfully updated, false otherwise
11
- def self.update(klass, query, setter)
12
- klass.collection.update(query, setter, safe: true)['n'] == 1
13
- end
14
-
15
- # Determine whether the provided document is locked in the database or not.
16
- #
17
- # @param [Class] The model instance
18
- # @return [Time] The timestamp of when the document is locked until, nil if not locked.
19
- def self.locked_until(doc)
20
- existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
21
- existing = doc.class.collection.find_one(existing_query, fields: { doc.locked_until_field => 1 })
22
- existing ? existing[doc.locked_until_field] : nil
23
- end
24
- end
25
- end
26
- end
@@ -1,26 +0,0 @@
1
- module Mongoid
2
- module Locker
3
- # Normalizes queries between various Mongoid versions.
4
- module Wrapper
5
- # Update the document for the provided Class matching the provided query with the provided setter.
6
- #
7
- # @param [Class] The model class
8
- # @param [Hash] The Mongoid query
9
- # @param [Hash] The Mongoid setter
10
- # @return [Boolean] true if the document was successfully updated, false otherwise
11
- def self.update(klass, query, setter)
12
- klass.with(safe: true).collection.find(query).update(setter)['n'] == 1
13
- end
14
-
15
- # Determine whether the provided document is locked in the database or not.
16
- #
17
- # @param [Class] The model instance
18
- # @return [Time] The timestamp of when the document is locked until, nil if not locked.
19
- def self.locked_until(doc)
20
- existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
21
- existing = doc.class.where(existing_query).limit(1).only(doc.locked_until_field).first
22
- existing ? existing[doc.locked_until_field] : nil
23
- end
24
- end
25
- end
26
- end