mongoid-locker 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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