madeleine 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ #
2
+ # Wrapper for Ruby's file services, replaced during testing
3
+ # so we can run tests without touching a real filesystem.
4
+ #
5
+
6
+ class FileService
7
+
8
+ def open(*args)
9
+ super(*args)
10
+ end
11
+
12
+ def exist?(name)
13
+ File.exist?(name)
14
+ end
15
+
16
+ def dir_entries(name)
17
+ Dir.entries(name)
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ #
2
+ # Author:: Anders Bengtsson <ndrsbngtssn@yahoo.se>
3
+ # Copyright:: Copyright (c) 2004
4
+ #
5
+
6
+ require 'zlib'
7
+
8
+ module Madeleine
9
+ #
10
+ # Snapshot marshaller for compressed snapshots.
11
+ #
12
+ # Compresses the snapshots created by another marshaller. Uses either
13
+ # Marshal (the default) or another supplied marshaller.
14
+ #
15
+ # Uses <tt>zlib</tt> to do on-the-fly compression/decompression.
16
+ #
17
+ # ZMarshal works with Ruby's own Marshal and YAML, but not with SOAP
18
+ # marshalling.
19
+ #
20
+ # Usage:
21
+ #
22
+ # require 'madeleine'
23
+ # require 'madeleine/zmarshal'
24
+ #
25
+ # marshaller = Madeleine::ZMarshal.new(YAML)
26
+ # madeleine = SnapshotMadeleine.new("my_example_storage", marshaller) {
27
+ # SomeExampleApplication.new()
28
+ # }
29
+ #
30
+ class ZMarshal
31
+
32
+ def initialize(marshaller=Marshal)
33
+ @marshaller = marshaller
34
+ end
35
+
36
+ def load(stream)
37
+ zstream = Zlib::GzipReader.new(stream)
38
+ begin
39
+ # Buffer into a string first, since GzipReader can't handle
40
+ # Marshal's 0-sized reads and SOAP can't handle streams at all.
41
+ # In a bright future we can revert to reading directly from the
42
+ # stream again.
43
+ buffer = zstream.read
44
+ return @marshaller.load(buffer)
45
+ ensure
46
+ zstream.finish
47
+ end
48
+ end
49
+
50
+ def dump(system, stream)
51
+ zstream = Zlib::GzipWriter.new(stream)
52
+ begin
53
+ @marshaller.dump(system, zstream)
54
+ ensure
55
+ zstream.finish
56
+ end
57
+ nil
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,73 @@
1
+ #
2
+ # Simple example of using time with Madeleine.
3
+ #
4
+
5
+ $LOAD_PATH.unshift(".." + File::SEPARATOR + "lib")
6
+
7
+ require 'madeleine/clock'
8
+ require 'tk'
9
+
10
+ # The Clicker keeps track of when it was last clicked.
11
+ #
12
+ # To access the time it extends ClockedSystem, which provides
13
+ # it with the 'clock' attribute.
14
+ #
15
+ class Clicker
16
+ include Madeleine::Clock::ClockedSystem
17
+
18
+ def initialize
19
+ @last_clicked = nil
20
+ end
21
+
22
+ def click
23
+ @last_clicked = clock.time
24
+ end
25
+
26
+ def last_clicked
27
+ return '-' if @last_clicked.nil?
28
+ @last_clicked.to_s
29
+ end
30
+ end
31
+
32
+ # A command to update the Clicker with.
33
+ #
34
+ class Click
35
+ def execute(system)
36
+ system.click
37
+ end
38
+ end
39
+
40
+ # Launch a ClockedSnapshotMadeleine.
41
+ #
42
+ # ClockedSnapshotMadeleine works like the regular SnapshotMadeleine, but
43
+ # optimizes away redundant commands from TimeActor.
44
+ #
45
+ madeleine = ClockedSnapshotMadeleine.new("clock-demo") { Clicker.new }
46
+
47
+ # Launch the TimeActor.
48
+ #
49
+ # This provides time commands, without which the system's time would stand still.
50
+ #
51
+ Madeleine::Clock::TimeActor.launch(madeleine)
52
+
53
+ clicker = madeleine.system
54
+
55
+ # The GUI
56
+
57
+ root = TkRoot.new() { title "Madeleine Clock Example" }
58
+ label = TkLabel.new(root) {
59
+ text "Last clicked " + clicker.last_clicked
60
+ width 40
61
+ pack
62
+ }
63
+ button = TkButton.new(root) {
64
+ text 'Click'
65
+ command proc {
66
+ madeleine.execute_command(Click.new)
67
+ label.text("Last clicked " + clicker.last_clicked)
68
+ }
69
+ pack
70
+ }
71
+
72
+ Tk.mainloop
73
+
@@ -0,0 +1,23 @@
1
+ #
2
+ # Dictionary client
3
+ #
4
+ # See dictionary_server.rb for details
5
+ #
6
+
7
+ require 'drb'
8
+
9
+ DRb.start_service
10
+ dictionary = DRbObject.new(nil, "druby://localhost:1234")
11
+
12
+ if ARGV.length == 1
13
+ puts dictionary.lookup(ARGV[0])
14
+ elsif ARGV.length == 2
15
+ dictionary.add(ARGV[0], ARGV[1])
16
+ puts "Stored"
17
+ else
18
+ puts "Usage: dictionary_client <key> [<value>]"
19
+ end
20
+
21
+
22
+
23
+
@@ -0,0 +1,94 @@
1
+ #
2
+ # A dictionary server using Distributed Ruby (DRb).
3
+ #
4
+ # All modifications to the dictionary are done as commands,
5
+ # while read-only queries (i.e 'lookup') are done directly.
6
+ #
7
+ # First launch this server in the background, then use
8
+ # dictionary_client.rb to look up and add items to the
9
+ # dictionary.
10
+ # You can kill the server at any time. The contents of the
11
+ # dictionary will still be there when you restart it.
12
+ #
13
+ # DRb is available at http://raa.ruby-lang.org/list.rhtml?name=druby
14
+ #
15
+
16
+ $LOAD_PATH.unshift(".." + File::SEPARATOR + "lib")
17
+ require 'madeleine'
18
+
19
+ require 'drb'
20
+
21
+
22
+ class Dictionary
23
+ def initialize
24
+ @data = {}
25
+ end
26
+
27
+ def add(key, value)
28
+ @data[key] = value
29
+ end
30
+
31
+ def lookup(key)
32
+ @data[key]
33
+ end
34
+ end
35
+
36
+
37
+ class Addition
38
+ def initialize(key, value)
39
+ @key, @value = key, value
40
+ end
41
+
42
+ def execute(system)
43
+ system.add(@key, @value)
44
+ end
45
+ end
46
+
47
+
48
+ class Lookup
49
+ def initialize(key)
50
+ @key = key
51
+ end
52
+
53
+ def execute(system)
54
+ system.lookup(@key)
55
+ end
56
+ end
57
+
58
+
59
+ class DictionaryServer
60
+
61
+ def initialize(madeleine)
62
+ @madeleine = madeleine
63
+ @dictionary = madeleine.system
64
+ end
65
+
66
+ def add(key, value)
67
+ # When adding a new key-value pair we modify the system, so
68
+ # this operation has to be done through a command.
69
+ @madeleine.execute_command(Addition.new(key, value))
70
+ end
71
+
72
+ def lookup(key)
73
+ # A lookup is a read-only operation, so we can do it as a non-logged
74
+ # query. If we weren't worried about concurrency problems we could
75
+ # have just called @dictionary.lookup(key) directly instead.
76
+ @madeleine.execute_query(Lookup.new(key))
77
+ end
78
+ end
79
+
80
+
81
+ madeleine = SnapshotMadeleine.new("dictionary-base") { Dictionary.new }
82
+
83
+ Thread.new(madeleine) {
84
+ puts "Taking snapshot every 30 seconds."
85
+ while true
86
+ sleep(30)
87
+ madeleine.take_snapshot
88
+ end
89
+ }
90
+
91
+ DRb.start_service("druby://localhost:1234",
92
+ DictionaryServer.new(madeleine))
93
+ DRb.thread.join
94
+
@@ -0,0 +1,60 @@
1
+ #
2
+ # Simple drawing program to show Madeleine's logging feature.
3
+ #
4
+ # When you restart the program, your old artwork is still there.
5
+ #
6
+ # (Note: The GUI components used here aren't marshal-able,
7
+ # so in a real app you would have to do custom marshaling for
8
+ # the Painter class to get working snapshots. Then again, in a real
9
+ # app you wouldn't use the GUI components to hold the app's data,
10
+ # would you?)
11
+ #
12
+
13
+ $LOAD_PATH.unshift(".." + File::SEPARATOR + "lib")
14
+
15
+ require 'madeleine'
16
+
17
+ require 'tkclass'
18
+
19
+ class Painter
20
+
21
+ def initialize(canvas)
22
+ @canvas = canvas
23
+ end
24
+
25
+ def draw(x, y)
26
+ line = Line.new(@canvas, x, y, x + 1, y + 1)
27
+ line.fill('black')
28
+ end
29
+ end
30
+
31
+ class PaintCommand
32
+
33
+ def initialize(x, y)
34
+ @x, @y = x, y
35
+ end
36
+
37
+ def execute(system)
38
+ system.draw(@x, @y)
39
+ end
40
+ end
41
+
42
+ root = TkRoot.new() { title "Madeleine Painter" }
43
+ canvas = Canvas.new(root)
44
+ canvas.pack
45
+
46
+ $madeleine = Madeleine::SnapshotMadeleine.new("painter-demo") { Painter.new(canvas) }
47
+
48
+ canvas.bind("1",
49
+ proc {|x, y|
50
+ $madeleine.execute_command(PaintCommand.new(x, y))
51
+ },
52
+ "%x %y")
53
+ canvas.bind("B1-Motion",
54
+ proc {|x, y|
55
+ $madeleine.execute_command(PaintCommand.new(x, y))
56
+ },
57
+ "%x %y")
58
+
59
+ Tk.mainloop
60
+
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.4
3
+ specification_version: 1
4
+ name: madeleine
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.7.1
7
+ date: 2005-01-06
8
+ summary: Madeleine is a Ruby implementation of Object Prevalence
9
+ require_paths:
10
+ - lib
11
+ email: ndrsbngtssn@yahoo.se
12
+ homepage: http://madeleine.sourceforge.net
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: madeleine
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.8.1
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Anders Bengtsson
29
+ files:
30
+ - lib/madeleine.rb
31
+ - lib/madeleine/automatic.rb
32
+ - lib/madeleine/clock.rb
33
+ - lib/madeleine/files.rb
34
+ - lib/madeleine/zmarshal.rb
35
+ - samples/clock_click.rb
36
+ - samples/dictionary_client.rb
37
+ - samples/dictionary_server.rb
38
+ - samples/painter.rb
39
+ - contrib/batched.rb
40
+ - contrib/benchmark.rb
41
+ - contrib/test_batched.rb
42
+ - contrib/test_scalability.rb
43
+ - contrib/threaded_benchmark.rb
44
+ - README
45
+ - NEWS
46
+ - COPYING
47
+ test_files: []
48
+ rdoc_options: []
49
+ extra_rdoc_files: []
50
+ executables: []
51
+ extensions: []
52
+ requirements: []
53
+ dependencies: []