pulse-meter-client-backport 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,12 +10,23 @@ module PulseMeter
10
10
  module InstanceMethods
11
11
  # Serializes object and saves it to Redis
12
12
  # @raise [DumpError] if dumping fails for any reason
13
- def dump!
13
+ def dump!(safe = true)
14
14
  ensure_storability!
15
- serialized_obj = self.to_yaml
16
- redis.hset(DUMP_REDIS_KEY, self.name, serialized_obj)
17
- rescue
18
- raise DumpError, "object cannot be dumped"
15
+ serialized_obj = to_yaml
16
+ if safe
17
+ unless redis.hsetnx(DUMP_REDIS_KEY, name, serialized_obj)
18
+ stored = self.class.restore(name)
19
+ unless stored.class == self.class
20
+ raise DumpConflictError, "Attempt to create sensor #{name} of class #{self.class} but it already has class #{stored.class}"
21
+ end
22
+ end
23
+ else
24
+ redis.hset(DUMP_REDIS_KEY, name, serialized_obj)
25
+ end
26
+ rescue DumpError, RestoreError => exc
27
+ raise exc
28
+ rescue StandardError => exc
29
+ raise DumpError, "object cannot be dumped: #{exc}"
19
30
  end
20
31
 
21
32
  # Ensures that object is dumpable
@@ -37,6 +37,9 @@ module PulseMeter
37
37
  # Exception to be raised when sensor cannot be dumped
38
38
  class DumpError < SensorError; end
39
39
 
40
+ # Exception to be raised on attempts of using the same key for different sensors
41
+ class DumpConflictError < DumpError; end
42
+
40
43
  # Exception to be raised when sensor cannot be restored
41
44
  class RestoreError < SensorError; end
42
45
 
@@ -1,3 +1,3 @@
1
1
  module PulseMeter
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -8,19 +8,23 @@ describe PulseMeter::Mixins::Dumper do
8
8
  class Bad < Base; end
9
9
 
10
10
  class Good < Base
11
- attr_accessor :foo
12
- def name; foo.to_s; end
11
+ attr_accessor :some_value
12
+ attr_accessor :name
13
13
 
14
14
  def redis; PulseMeter.redis; end
15
15
 
16
- def initialize(foo)
17
- @foo = foo
16
+ def initialize(name)
17
+ @name = name.to_s
18
+ @some_value = name
18
19
  end
19
20
  end
20
21
 
22
+ class GoodButAnother < Good; end
23
+
21
24
  let(:bad_obj){ Bad.new }
22
25
  let(:good_obj){ Good.new(:foo) }
23
26
  let(:another_good_obj){ Good.new(:bar) }
27
+ let(:good_obj_of_another_type){ GoodButAnother.new(:quux) }
24
28
  let(:redis){ PulseMeter.redis }
25
29
 
26
30
  describe '#dump' do
@@ -57,6 +61,23 @@ describe PulseMeter::Mixins::Dumper do
57
61
  expect {good_obj.dump!}.to change {redis.hlen(Good::DUMP_REDIS_KEY)}.by(1)
58
62
  end
59
63
  end
64
+
65
+ context "when dump is safe" do
66
+ it "should not overwrite stored objects of the same type" do
67
+ good_obj.some_value = 123
68
+ good_obj.dump!
69
+ good_obj.some_value = 321
70
+ good_obj.dump!
71
+ Base.restore(good_obj.name).some_value.should == 123
72
+ end
73
+
74
+ it "should raise DumpConflictError exception if sensor with the same name but different type already exists" do
75
+ good_obj.name = "duplicate_name"
76
+ good_obj_of_another_type.name = "duplicate_name"
77
+ good_obj.dump!
78
+ expect{good_obj_of_another_type.dump!}.to raise_exception(PulseMeter::DumpConflictError)
79
+ end
80
+ end
60
81
  end
61
82
 
62
83
  describe ".restore" do
@@ -77,14 +98,14 @@ describe PulseMeter::Mixins::Dumper do
77
98
 
78
99
  it "should restore object data" do
79
100
  restored = Base.restore(good_obj.name)
80
- restored.foo.should == good_obj.foo
101
+ restored.some_value.should == good_obj.some_value
81
102
  end
82
103
 
83
104
  it "should restore last dumped object" do
84
- good_obj.foo = :bar
85
- good_obj.dump!
105
+ good_obj.some_value = :bar
106
+ good_obj.dump!(false)
86
107
  restored = Base.restore(good_obj.name)
87
- restored.foo.should == :bar
108
+ restored.some_value.should == :bar
88
109
  end
89
110
  end
90
111
  end
@@ -106,8 +127,8 @@ describe PulseMeter::Mixins::Dumper do
106
127
  end
107
128
 
108
129
  it "should return list of registered objects" do
109
- good_obj.dump!
110
- another_good_obj.dump!
130
+ good_obj.dump!(false)
131
+ another_good_obj.dump!(false)
111
132
  Base.list_names.should =~ [good_obj.name, another_good_obj.name]
112
133
  end
113
134
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pulse-meter-client-backport
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ilya Averyanov
@@ -16,12 +16,10 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-06-06 00:00:00 Z
19
+ date: 2012-06-08 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: json
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
23
  none: false
26
24
  requirements:
27
25
  - - ">="
@@ -30,12 +28,12 @@ dependencies:
30
28
  segments:
31
29
  - 0
32
30
  version: "0"
31
+ prerelease: false
33
32
  type: :runtime
34
- version_requirements: *id001
33
+ name: json
34
+ requirement: *id001
35
35
  - !ruby/object:Gem::Dependency
36
- name: redis
37
- prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
37
  none: false
40
38
  requirements:
41
39
  - - ">="
@@ -44,12 +42,12 @@ dependencies:
44
42
  segments:
45
43
  - 0
46
44
  version: "0"
45
+ prerelease: false
47
46
  type: :runtime
48
- version_requirements: *id002
47
+ name: redis
48
+ requirement: *id002
49
49
  - !ruby/object:Gem::Dependency
50
- name: hashie
51
- prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
50
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
51
  none: false
54
52
  requirements:
55
53
  - - ">="
@@ -58,12 +56,12 @@ dependencies:
58
56
  segments:
59
57
  - 0
60
58
  version: "0"
59
+ prerelease: false
61
60
  type: :development
62
- version_requirements: *id003
61
+ name: hashie
62
+ requirement: *id003
63
63
  - !ruby/object:Gem::Dependency
64
- name: foreman
65
- prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
64
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
65
  none: false
68
66
  requirements:
69
67
  - - ">="
@@ -72,12 +70,12 @@ dependencies:
72
70
  segments:
73
71
  - 0
74
72
  version: "0"
73
+ prerelease: false
75
74
  type: :development
76
- version_requirements: *id004
75
+ name: foreman
76
+ requirement: *id004
77
77
  - !ruby/object:Gem::Dependency
78
- name: mock_redis
79
- prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
78
+ version_requirements: &id005 !ruby/object:Gem::Requirement
81
79
  none: false
82
80
  requirements:
83
81
  - - ">="
@@ -86,12 +84,12 @@ dependencies:
86
84
  segments:
87
85
  - 0
88
86
  version: "0"
87
+ prerelease: false
89
88
  type: :development
90
- version_requirements: *id005
89
+ name: mock_redis
90
+ requirement: *id005
91
91
  - !ruby/object:Gem::Dependency
92
- name: rack-test
93
- prerelease: false
94
- requirement: &id006 !ruby/object:Gem::Requirement
92
+ version_requirements: &id006 !ruby/object:Gem::Requirement
95
93
  none: false
96
94
  requirements:
97
95
  - - ">="
@@ -100,12 +98,12 @@ dependencies:
100
98
  segments:
101
99
  - 0
102
100
  version: "0"
101
+ prerelease: false
103
102
  type: :development
104
- version_requirements: *id006
103
+ name: rack-test
104
+ requirement: *id006
105
105
  - !ruby/object:Gem::Dependency
106
- name: rake
107
- prerelease: false
108
- requirement: &id007 !ruby/object:Gem::Requirement
106
+ version_requirements: &id007 !ruby/object:Gem::Requirement
109
107
  none: false
110
108
  requirements:
111
109
  - - ">="
@@ -114,12 +112,12 @@ dependencies:
114
112
  segments:
115
113
  - 0
116
114
  version: "0"
115
+ prerelease: false
117
116
  type: :development
118
- version_requirements: *id007
117
+ name: rake
118
+ requirement: *id007
119
119
  - !ruby/object:Gem::Dependency
120
- name: redcarpet
121
- prerelease: false
122
- requirement: &id008 !ruby/object:Gem::Requirement
120
+ version_requirements: &id008 !ruby/object:Gem::Requirement
123
121
  none: false
124
122
  requirements:
125
123
  - - ">="
@@ -128,12 +126,12 @@ dependencies:
128
126
  segments:
129
127
  - 0
130
128
  version: "0"
129
+ prerelease: false
131
130
  type: :development
132
- version_requirements: *id008
131
+ name: redcarpet
132
+ requirement: *id008
133
133
  - !ruby/object:Gem::Dependency
134
- name: rspec
135
- prerelease: false
136
- requirement: &id009 !ruby/object:Gem::Requirement
134
+ version_requirements: &id009 !ruby/object:Gem::Requirement
137
135
  none: false
138
136
  requirements:
139
137
  - - ">="
@@ -142,12 +140,12 @@ dependencies:
142
140
  segments:
143
141
  - 0
144
142
  version: "0"
143
+ prerelease: false
145
144
  type: :development
146
- version_requirements: *id009
145
+ name: rspec
146
+ requirement: *id009
147
147
  - !ruby/object:Gem::Dependency
148
- name: timecop
149
- prerelease: false
150
- requirement: &id010 !ruby/object:Gem::Requirement
148
+ version_requirements: &id010 !ruby/object:Gem::Requirement
151
149
  none: false
152
150
  requirements:
153
151
  - - ">="
@@ -156,12 +154,12 @@ dependencies:
156
154
  segments:
157
155
  - 0
158
156
  version: "0"
157
+ prerelease: false
159
158
  type: :development
160
- version_requirements: *id010
159
+ name: timecop
160
+ requirement: *id010
161
161
  - !ruby/object:Gem::Dependency
162
- name: yard
163
- prerelease: false
164
- requirement: &id011 !ruby/object:Gem::Requirement
162
+ version_requirements: &id011 !ruby/object:Gem::Requirement
165
163
  none: false
166
164
  requirements:
167
165
  - - ">="
@@ -170,8 +168,10 @@ dependencies:
170
168
  segments:
171
169
  - 0
172
170
  version: "0"
171
+ prerelease: false
173
172
  type: :development
174
- version_requirements: *id011
173
+ name: yard
174
+ requirement: *id011
175
175
  description: Ruby 1.8 compatible PulseMeter client
176
176
  email:
177
177
  - av@fun-box.ru