rufus-cloche 0.1.9 → 0.1.10
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.
- data/CHANGELOG.txt +6 -0
- data/LICENSE.txt +1 -1
- data/lib/rufus/cloche.rb +37 -37
- data/rufus-cloche.gemspec +3 -2
- data/test/con/put_vs_delete.rb +31 -0
- data/test/test.rb +4 -1
- metadata +3 -2
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
= rufus-cloche CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-cloche - 0.1.10 released 2010/01/03
|
6
|
+
|
7
|
+
- increased mutex coverage (though flock matters more)
|
8
|
+
- now put doesn't touch passed doc unless :update_rev => true
|
9
|
+
|
10
|
+
|
5
11
|
== rufus-cloche - 0.1.9 released 2009/12/29
|
6
12
|
|
7
13
|
- put returns true when document is gone
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2009-
|
2
|
+
Copyright (c) 2009-2010, John Mettraux, jmettraux@gmail.com
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
data/lib/rufus/cloche.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2009-
|
2
|
+
# Copyright (c) 2009-2010, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -31,6 +31,7 @@ rescue LoadError
|
|
31
31
|
require 'json'
|
32
32
|
end
|
33
33
|
require 'rufus/json'
|
34
|
+
Rufus::Json.detect_backend
|
34
35
|
|
35
36
|
|
36
37
|
module Rufus
|
@@ -42,7 +43,7 @@ module Rufus
|
|
42
43
|
#
|
43
44
|
class Cloche
|
44
45
|
|
45
|
-
VERSION = '0.1.
|
46
|
+
VERSION = '0.1.10'
|
46
47
|
|
47
48
|
attr_reader :dir
|
48
49
|
|
@@ -65,7 +66,10 @@ module Rufus
|
|
65
66
|
#
|
66
67
|
# If the put is successful, nil is returned.
|
67
68
|
#
|
68
|
-
def put (doc)
|
69
|
+
def put (doc, opts={})
|
70
|
+
|
71
|
+
doc = Rufus::Json.dup(doc) unless opts[:update_rev]
|
72
|
+
# work with a copy, don't touch orgiinal
|
69
73
|
|
70
74
|
type, key = doc['type'], doc['_id']
|
71
75
|
|
@@ -73,19 +77,13 @@ module Rufus
|
|
73
77
|
ArgumentError.new("missing values for keys 'type' and/or '_id'")
|
74
78
|
) if type.nil? || key.nil?
|
75
79
|
|
76
|
-
d, f = path_for(type, key)
|
77
|
-
fn = File.join(d, f)
|
78
|
-
|
79
80
|
rev = (doc['_rev'] ||= -1)
|
80
81
|
|
81
82
|
raise(
|
82
83
|
ArgumentError.new("values for '_rev' must be positive integers")
|
83
84
|
) if rev.class != Fixnum && rev.class != Bignum
|
84
85
|
|
85
|
-
|
86
|
-
FileUtils.touch(fn) unless File.exist?(fn)
|
87
|
-
|
88
|
-
lock(fn) do |file|
|
86
|
+
lock(true, type, key) do |file|
|
89
87
|
|
90
88
|
cur = do_get(file)
|
91
89
|
|
@@ -104,8 +102,9 @@ module Rufus
|
|
104
102
|
#
|
105
103
|
def get (type, key)
|
106
104
|
|
107
|
-
r = lock(type, key) { |f| do_get(f) }
|
108
|
-
|
105
|
+
r = lock(false, type, key) { |f| do_get(f) }
|
106
|
+
|
107
|
+
r == false ? nil : r
|
109
108
|
end
|
110
109
|
|
111
110
|
# Attempts at deleting a document. You have to pass the current version
|
@@ -127,7 +126,7 @@ module Rufus
|
|
127
126
|
|
128
127
|
type, key = doc['type'], doc['_id']
|
129
128
|
|
130
|
-
lock(type, key) do |f|
|
129
|
+
r = lock(false, type, key) do |f|
|
131
130
|
|
132
131
|
cur = do_get(f)
|
133
132
|
|
@@ -138,9 +137,11 @@ module Rufus
|
|
138
137
|
File.delete(f.path)
|
139
138
|
nil
|
140
139
|
rescue
|
141
|
-
|
140
|
+
false
|
142
141
|
end
|
143
142
|
end
|
143
|
+
|
144
|
+
r == false ? true : nil
|
144
145
|
end
|
145
146
|
|
146
147
|
# Given a type, this method will return an array of all the documents for
|
@@ -217,36 +218,35 @@ module Rufus
|
|
217
218
|
[ File.join(dir_for(type), subdir), "#{nkey}.json" ]
|
218
219
|
end
|
219
220
|
|
220
|
-
def
|
221
|
+
def lock (create, type, key, &block)
|
221
222
|
|
222
|
-
|
223
|
-
|
224
|
-
elsif type_or_doc.is_a?(String)
|
225
|
-
type_or_doc
|
226
|
-
else # it's a doc (Hash)
|
227
|
-
File.join(*path_for(type_or_doc['type'], type_or_doc['_id']))
|
228
|
-
end
|
223
|
+
@mutex.synchronize do
|
224
|
+
begin
|
229
225
|
|
230
|
-
|
231
|
-
|
226
|
+
d, f = path_for(type, key)
|
227
|
+
fn = File.join(d, f)
|
232
228
|
|
233
|
-
|
229
|
+
if create && ( ! File.exist?(fn))
|
230
|
+
FileUtils.mkdir_p(d) unless File.exist?(d)
|
231
|
+
FileUtils.touch(fn) unless File.exist?(fn)
|
232
|
+
end
|
234
233
|
|
235
|
-
|
234
|
+
file = File.new(fn) rescue nil
|
236
235
|
|
237
|
-
|
236
|
+
return false if file.nil?
|
238
237
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
238
|
+
file.flock(File::LOCK_EX)
|
239
|
+
block.call(file)
|
240
|
+
|
241
|
+
ensure
|
242
|
+
begin
|
243
|
+
file.flock(File::LOCK_UN)
|
244
|
+
rescue Exception => e
|
245
|
+
#p [ :lock, @fpath, e ]
|
246
|
+
#e.backtrace.each { |l| puts l }
|
247
|
+
end
|
248
|
+
file.close rescue nil
|
248
249
|
end
|
249
|
-
file.close rescue nil
|
250
250
|
end
|
251
251
|
end
|
252
252
|
end
|
data/rufus-cloche.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rufus-cloche}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.10"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Mettraux"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-03}
|
13
13
|
s.description = %q{
|
14
14
|
A very stupid JSON hash store.
|
15
15
|
|
@@ -33,6 +33,7 @@ Strives to be process-safe and thread-safe.
|
|
33
33
|
"lib/rufus/cloche.rb",
|
34
34
|
"rufus-cloche.gemspec",
|
35
35
|
"test/bm/bm0.rb",
|
36
|
+
"test/con/put_vs_delete.rb",
|
36
37
|
"test/ct_worker.rb",
|
37
38
|
"test/ct_writer.rb",
|
38
39
|
"test/test.rb"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
$:.unshift('lib')
|
3
|
+
|
4
|
+
require 'rufus/cloche'
|
5
|
+
|
6
|
+
workdir = File.join(File.dirname(__FILE__), '..', '..', 'tcloche')
|
7
|
+
|
8
|
+
FileUtils.rm_rf(workdir) rescue nil
|
9
|
+
|
10
|
+
C = Rufus::Cloche.new(:dir => workdir)
|
11
|
+
|
12
|
+
d = C.get('whatever', 'nada')
|
13
|
+
C.delete(d) if d
|
14
|
+
|
15
|
+
C.put({ '_id' => 'nada', 'where' => 'London', 'type' => 'whatever' })
|
16
|
+
$d = C.get('whatever', 'nada')
|
17
|
+
|
18
|
+
Thread.abort_on_exception = true
|
19
|
+
|
20
|
+
t1 = Thread.new do
|
21
|
+
p [ Thread.current.object_id, :delete, $d['_rev'], C.delete($d) ]
|
22
|
+
end
|
23
|
+
t0 = Thread.new do
|
24
|
+
p [ Thread.current.object_id, :put, $d['_rev'], C.put($d) ]
|
25
|
+
end
|
26
|
+
|
27
|
+
sleep 0.100
|
28
|
+
|
29
|
+
p C.get('whatever', 'nada')
|
30
|
+
p C.get('whatever', 'nada')
|
31
|
+
|
data/test/test.rb
CHANGED
@@ -35,9 +35,12 @@ class ClocheTest < Test::Unit::TestCase
|
|
35
35
|
|
36
36
|
def test_put
|
37
37
|
|
38
|
-
|
38
|
+
doc = { '_id' => 'john', 'type' => 'person', 'eyes' => 'green' }
|
39
|
+
|
40
|
+
r = @c.put(doc)
|
39
41
|
|
40
42
|
assert_nil r
|
43
|
+
assert_nil doc['_rev']
|
41
44
|
|
42
45
|
h = fetch('person', 'john')
|
43
46
|
assert_equal 0, h['_rev']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-cloche
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-03 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- lib/rufus/cloche.rb
|
56
56
|
- rufus-cloche.gemspec
|
57
57
|
- test/bm/bm0.rb
|
58
|
+
- test/con/put_vs_delete.rb
|
58
59
|
- test/ct_worker.rb
|
59
60
|
- test/ct_writer.rb
|
60
61
|
- test/test.rb
|