madeleine 0.8.0 → 0.9.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0254e4a5cd6fe35768ce76fb92b0804724a83663
4
+ data.tar.gz: cc5860e5c27def4543d104edc0ce30f0f6acf65a
5
+ SHA512:
6
+ metadata.gz: e009aac28e96a06499feeff40c43156bc8dfa7139ae20588fc2c5eef88277868b77cbff63be153971b59230e956b35b91483783dd8983ce6e33a8837c301a343
7
+ data.tar.gz: c5c67ada967d93f9d280ade1304c07328b439acf4aa787e5c1441d68213394252c4bd8a1227a3f8485db46cfe98856969360b08e07fd896dcdc08ea87b4c65d2
@@ -1,3 +1,5 @@
1
+ * Ruby 2.0 fix for self-tests.
2
+
1
3
  Madeleine 0.8.0 (December 17, 2012):
2
4
 
3
5
  * Ruby 1.9 compatible (requires at least 1.8.7)
@@ -0,0 +1,84 @@
1
+ # Madeleine
2
+
3
+ Madeleine is a Ruby implementation of transparent persistence of business
4
+ objects, using command logging and complete system snapshots.
5
+
6
+ https://github.com/ghostganz/madeleine
7
+
8
+ ### Usage
9
+
10
+ ```ruby
11
+ require 'madeleine'
12
+
13
+ # Create an application as a prevalent system
14
+
15
+ madeleine = SnapshotMadeleine.new("my_example_storage") {
16
+ # Creating the initial empty system. This is how the application
17
+ # is bootstrapped on each startup (until the first snapshot is taken).
18
+ # All the persistent data needs to be reachable from this object.
19
+ # For this example, the application's whole dataset is a hash
20
+ # with a counter:
21
+ {:counter => 0}
22
+ }
23
+
24
+ # To operate on the system, we need commands. For this example,
25
+ # we can do additions to our counter:
26
+ class AdditionCommand
27
+ def initialize(number)
28
+ @number = number
29
+ end
30
+
31
+ def execute(system)
32
+ # This is the only place from where we're allowed to modify
33
+ # the system.
34
+ system[:counter] += @number
35
+ end
36
+ end
37
+
38
+ # Do modifications of the system by sending commands through
39
+ # the Madeleine instance:
40
+
41
+ command = AdditionCommand.new(12)
42
+ madeleine.execute_command(command)
43
+
44
+ # The commands are written to the command log before executed.
45
+ # The next time the application starts, all the commands in the
46
+ # log are re-applied to the system, returning it to the state it
47
+ # had when it was shut down.
48
+
49
+ # To avoid long start-up times when the command log gets large,
50
+ # you can do occasional snapshots of the entire system. You must
51
+ # also do a snapshot before deploying any changes in your application
52
+ # logic.
53
+
54
+ madeleine.take_snapshot
55
+ ```
56
+
57
+ ### Requirements
58
+
59
+ * Ruby 1.8.7 or later
60
+
61
+ ### Contact
62
+
63
+ Homepage: https://github.com/ghostganz/madeleine
64
+
65
+ ### License
66
+
67
+ BSD (see the file ```COPYING```)
68
+
69
+ ### Credits
70
+
71
+ Anders Bengtsson - Prevalence core impl.
72
+ Stephen Sykes - Automatic commands impl.
73
+
74
+ Madeleine's design is based on Prevayler, the original Java
75
+ prevalence layer.
76
+
77
+ With the help of patches, testing and feedback from:
78
+
79
+ Steve Conover, David Heinemeier Hansson, Johan Lind, Håkan Råberg,
80
+ IIMA Susumu, Martin Tampe and Jon Tirsén
81
+
82
+ Thanks to Klaus Wuestefeld and the Prevayler developers for the
83
+ model of this software; to Minero Aoki for the installer; to Matz and
84
+ the core developers for the Ruby language!
@@ -42,21 +42,32 @@ module Madeleine
42
42
  # See: DefaultSnapshotMadeleine
43
43
  #
44
44
  # * <tt>directory_name</tt> - Storage directory to use. Will be created if needed.
45
- # * <tt>snapshot_marshaller</tt> - Marshaller to use for system snapshots. (Optional)
45
+ # * <tt>options</tt> - Options hash:
46
+ # * <tt>:snapshot_marshaller</tt> - Marshaller to use for system snapshots (defaults to Marshal)
47
+ # * <tt>:execution_context</tt> - Optional context to be passed to commands' execute() method as a second parameter
46
48
  # * <tt>new_system_block</tt> - Block to create a new system (if no stored system was found).
47
- def self.new(directory_name, snapshot_marshaller=Marshal, &new_system_block)
49
+ def self.new(directory_name, options = {}, &new_system_block)
50
+ if options.kind_of? Hash
51
+ options = {
52
+ :snapshot_marshaller => Marshal,
53
+ :execution_context => nil
54
+ }.merge(options)
55
+ else
56
+ # Backwards compat.
57
+ options = {:snapshot_marshaller => options}
58
+ end
59
+
48
60
  log_factory = DefaultLogFactory.new
49
61
  logger = Logger.new(directory_name,
50
62
  log_factory)
51
63
  snapshotter = Snapshotter.new(directory_name,
52
- snapshot_marshaller)
53
- lock = DefaultLock.new
64
+ options[:snapshot_marshaller])
54
65
  recoverer = Recoverer.new(directory_name,
55
- snapshot_marshaller)
66
+ options[:snapshot_marshaller])
56
67
  system = recoverer.recover_snapshot(new_system_block)
57
- executer = Executer.new(system)
68
+ executer = Executer.new(system, options[:execution_context])
58
69
  recoverer.recover_logs(executer)
59
- DefaultSnapshotMadeleine.new(system, logger, snapshotter, lock, executer)
70
+ DefaultSnapshotMadeleine.new(system, logger, snapshotter, executer)
60
71
  end
61
72
  end
62
73
 
@@ -65,13 +76,13 @@ module Madeleine
65
76
  # The prevalent system
66
77
  attr_reader :system
67
78
 
68
- def initialize(system, logger, snapshotter, lock, executer)
79
+ def initialize(system, logger, snapshotter, executer)
69
80
  SanityCheck.instance.run_once
70
81
 
71
82
  @system = system
72
83
  @logger = logger
73
84
  @snapshotter = snapshotter
74
- @lock = lock
85
+ @lock = Sync.new
75
86
  @executer = executer
76
87
 
77
88
  @closed = false
@@ -103,7 +114,7 @@ module Madeleine
103
114
  #
104
115
  # * <tt>query</tt> - The query command to execute
105
116
  def execute_query(query)
106
- @lock.synchronize_shared do
117
+ @lock.synchronize(:SH) do
107
118
  @executer.execute(query)
108
119
  end
109
120
  end
@@ -168,31 +179,20 @@ module Madeleine
168
179
 
169
180
  FILE_COUNTER_SIZE = 21 #:nodoc:
170
181
 
171
- class DefaultLock #:nodoc:
172
-
173
- def initialize
174
- @lock = Sync.new
175
- end
176
-
177
- def synchronize(&block)
178
- @lock.synchronize(&block)
179
- end
180
-
181
- def synchronize_shared(&block)
182
- @lock.synchronize(:SH, &block)
183
- end
184
- end
185
-
186
182
  class Executer #:nodoc:
187
-
188
- def initialize(system)
183
+ def initialize(system, context = nil)
189
184
  @system = system
185
+ @context = context
190
186
  @in_recovery = false
191
187
  end
192
188
 
193
189
  def execute(command)
194
190
  begin
195
- command.execute(@system)
191
+ if @context
192
+ command.execute(@system, @context)
193
+ else
194
+ command.execute(@system)
195
+ end
196
196
  rescue
197
197
  raise unless @in_recovery
198
198
  end
@@ -231,7 +231,7 @@ module Madeleine
231
231
  def recover_logs(executer)
232
232
  executer.recovery do
233
233
  CommandLog.log_file_names(@directory_name, FileService.new).each do |file_name|
234
- open(@directory_name + File::SEPARATOR + file_name, "rb") do |log|
234
+ open("#{@directory_name}#{File::SEPARATOR}#{file_name}", "rb") do |log|
235
235
  recover_log(executer, log)
236
236
  end
237
237
  end
@@ -255,11 +255,13 @@ module Madeleine
255
255
  end
256
256
 
257
257
  def name
258
- result = @path
259
- result += File::SEPARATOR
260
- result += sprintf("%0#{FILE_COUNTER_SIZE}d", @id)
261
- result += '.'
262
- result += @name
258
+ [
259
+ @path,
260
+ File::SEPARATOR,
261
+ sprintf("%0#{FILE_COUNTER_SIZE}d", @id),
262
+ '.',
263
+ @name
264
+ ].join
263
265
  end
264
266
  end
265
267
 
@@ -363,7 +365,7 @@ module Madeleine
363
365
  private
364
366
 
365
367
  def delete_log_files
366
- names = Dir.glob(@directory_name + File::SEPARATOR + "*.command_log")
368
+ names = Dir.glob("#{@directory_name}#{File::SEPARATOR}*.command_log")
367
369
  names.each do |name|
368
370
  name.untaint
369
371
  File.delete(name)
@@ -1,3 +1,4 @@
1
+ #encoding:utf-8
1
2
  #
2
3
  # Author:: Anders Bengtsson <ndrsbngtssn@yahoo.se>
3
4
  # Copyright:: Copyright (c) 2004-2006
@@ -11,7 +12,11 @@ module Madeleine
11
12
  include Singleton
12
13
 
13
14
  def initialize
14
- @testdata = "\x85\x00\x0a\0x0d\x0a".freeze
15
+ @testdata = "\x85\x00\x0a\0x0d\x0a"
16
+ if @testdata.respond_to?(:force_encoding)
17
+ @testdata.force_encoding('ASCII-8BIT')
18
+ end
19
+ @testdata.freeze
15
20
  @was_run = false
16
21
  end
17
22
 
@@ -1,3 +1,3 @@
1
1
  module Madeleine
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0.pre"
3
3
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: madeleine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
5
- prerelease:
4
+ version: 0.9.0.pre
6
5
  platform: ruby
7
6
  authors:
8
- - Anders Bengtsson
7
+ - Anders Kindberg (Bengtsson)
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
11
+ date: 2013-08-25 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: minitest
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,33 +27,29 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rdoc
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: Transparent persistence of system state using logging and snapshots
@@ -81,11 +74,12 @@ files:
81
74
  - contrib/test_batched.rb
82
75
  - contrib/test_scalability.rb
83
76
  - contrib/threaded_benchmark.rb
84
- - README
77
+ - README.md
85
78
  - CHANGES.txt
86
79
  - COPYING
87
80
  homepage: http://github.com/ghostganz/madeleine
88
81
  licenses: []
82
+ metadata: {}
89
83
  post_install_message:
90
84
  rdoc_options:
91
85
  - --exclude
@@ -97,21 +91,19 @@ rdoc_options:
97
91
  require_paths:
98
92
  - lib
99
93
  required_ruby_version: !ruby/object:Gem::Requirement
100
- none: false
101
94
  requirements:
102
- - - ! '>='
95
+ - - '>='
103
96
  - !ruby/object:Gem::Version
104
97
  version: 1.8.7
105
98
  required_rubygems_version: !ruby/object:Gem::Requirement
106
- none: false
107
99
  requirements:
108
- - - ! '>='
100
+ - - '>'
109
101
  - !ruby/object:Gem::Version
110
- version: '0'
102
+ version: 1.3.1
111
103
  requirements: []
112
104
  rubyforge_project:
113
- rubygems_version: 1.8.24
105
+ rubygems_version: 2.0.5
114
106
  signing_key:
115
- specification_version: 3
107
+ specification_version: 4
116
108
  summary: Madeleine is a Ruby implementation of Object Prevalence
117
109
  test_files: []
data/README DELETED
@@ -1,55 +0,0 @@
1
-
2
- Madeleine is a Ruby implementation of Object Prevalence: Transparent
3
- persistence of business objects using command logging and complete
4
- system snapshots.
5
-
6
- https://github.com/ghostganz/madeleine
7
-
8
- Madeleine's design is based on Prevayler, the original Java
9
- prevalence layer.
10
-
11
-
12
- Usage:
13
-
14
- require 'madeleine'
15
-
16
- # Create an application as a prevalent system
17
-
18
- madeleine = SnapshotMadeleine.new("my_example_storage") {
19
- SomeExampleApplication.new()
20
- }
21
-
22
- # Do modifications of the system by sending commands through
23
- # the Madeleine instance. A command is an object with a suitable
24
- # "execute(system)" method.
25
-
26
- madeleine.execute_command(command)
27
-
28
-
29
- Requirements:
30
-
31
- * Ruby 1.8.7 or later
32
-
33
- Contact:
34
-
35
- Homepage:
36
- https://github.com/ghostganz/madeleine
37
-
38
- License:
39
-
40
- BSD (see the file COPYING)
41
-
42
- Credits:
43
-
44
- Anders Bengtsson - Prevalence core impl.
45
- Stephen Sykes - Automatic commands impl.
46
-
47
- With the help of patches, testing and feedback from:
48
-
49
- Steve Conover, David Heinemeier Hansson, Johan Lind, Håkan Råberg,
50
- IIMA Susumu, Martin Tampe and Jon Tirsén
51
-
52
- Thanks to Klaus Wuestefeld and the Prevayler developers for the
53
- model of this software; to Minero Aoki for the installer; to Matz and
54
- the core developers for the Ruby language!
55
-