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 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-2009, John Mettraux, jmettraux@gmail.com
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-2009, John Mettraux, jmettraux@gmail.com
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.9'
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
- FileUtils.mkdir_p(d) unless File.exist?(d)
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
- r == true ? nil : r
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
- true
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 file_for (type_or_doc, key)
221
+ def lock (create, type, key, &block)
221
222
 
222
- fn = if key
223
- File.join(*path_for(type_or_doc, key))
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
- File.exist?(fn) ? (File.new(fn) rescue nil) : nil
231
- end
226
+ d, f = path_for(type, key)
227
+ fn = File.join(d, f)
232
228
 
233
- def lock (type_or_doc, key=nil, &block)
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
- file = file_for(type_or_doc, key)
234
+ file = File.new(fn) rescue nil
236
235
 
237
- return true if file.nil?
236
+ return false if file.nil?
238
237
 
239
- begin
240
- file.flock(File::LOCK_EX)
241
- @mutex.synchronize { block.call(file) }
242
- ensure
243
- begin
244
- file.flock(File::LOCK_UN)
245
- rescue Exception => e
246
- #p [ :lock, @fpath, e ]
247
- #e.backtrace.each { |l| puts l }
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.9"
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{2009-12-29}
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
- r = @c.put({ '_id' => 'john', 'type' => 'person', 'eyes' => 'green' })
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.9
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: 2009-12-29 00:00:00 +09:00
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