rufus-cloche 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|