lib/madeleine.rb in madeleine-0.8.0 vs lib/madeleine.rb in madeleine-0.9.0.pre

- old
+ new

@@ -40,40 +40,51 @@ # must use the same marshaller every time for a system. # # See: DefaultSnapshotMadeleine # # * <tt>directory_name</tt> - Storage directory to use. Will be created if needed. - # * <tt>snapshot_marshaller</tt> - Marshaller to use for system snapshots. (Optional) + # * <tt>options</tt> - Options hash: + # * <tt>:snapshot_marshaller</tt> - Marshaller to use for system snapshots (defaults to Marshal) + # * <tt>:execution_context</tt> - Optional context to be passed to commands' execute() method as a second parameter # * <tt>new_system_block</tt> - Block to create a new system (if no stored system was found). - def self.new(directory_name, snapshot_marshaller=Marshal, &new_system_block) + def self.new(directory_name, options = {}, &new_system_block) + if options.kind_of? Hash + options = { + :snapshot_marshaller => Marshal, + :execution_context => nil + }.merge(options) + else + # Backwards compat. + options = {:snapshot_marshaller => options} + end + log_factory = DefaultLogFactory.new logger = Logger.new(directory_name, log_factory) snapshotter = Snapshotter.new(directory_name, - snapshot_marshaller) - lock = DefaultLock.new + options[:snapshot_marshaller]) recoverer = Recoverer.new(directory_name, - snapshot_marshaller) + options[:snapshot_marshaller]) system = recoverer.recover_snapshot(new_system_block) - executer = Executer.new(system) + executer = Executer.new(system, options[:execution_context]) recoverer.recover_logs(executer) - DefaultSnapshotMadeleine.new(system, logger, snapshotter, lock, executer) + DefaultSnapshotMadeleine.new(system, logger, snapshotter, executer) end end class DefaultSnapshotMadeleine # The prevalent system attr_reader :system - def initialize(system, logger, snapshotter, lock, executer) + def initialize(system, logger, snapshotter, executer) SanityCheck.instance.run_once @system = system @logger = logger @snapshotter = snapshotter - @lock = lock + @lock = Sync.new @executer = executer @closed = false end @@ -101,11 +112,11 @@ # therefore isn't allowed to modify the system. A shared lock is held, preventing others # from modifying the system while the query is running. # # * <tt>query</tt> - The query command to execute def execute_query(query) - @lock.synchronize_shared do + @lock.synchronize(:SH) do @executer.execute(query) end end # Take a snapshot of the current system. @@ -166,35 +177,24 @@ # Internal classes below # FILE_COUNTER_SIZE = 21 #:nodoc: - class DefaultLock #:nodoc: - - def initialize - @lock = Sync.new - end - - def synchronize(&block) - @lock.synchronize(&block) - end - - def synchronize_shared(&block) - @lock.synchronize(:SH, &block) - end - end - class Executer #:nodoc: - - def initialize(system) + def initialize(system, context = nil) @system = system + @context = context @in_recovery = false end def execute(command) begin - command.execute(@system) + if @context + command.execute(@system, @context) + else + command.execute(@system) + end rescue raise unless @in_recovery end end @@ -229,11 +229,11 @@ end def recover_logs(executer) executer.recovery do CommandLog.log_file_names(@directory_name, FileService.new).each do |file_name| - open(@directory_name + File::SEPARATOR + file_name, "rb") do |log| + open("#{@directory_name}#{File::SEPARATOR}#{file_name}", "rb") do |log| recover_log(executer, log) end end end end @@ -253,15 +253,17 @@ def initialize(path, name, id) @path, @name, @id = path, name, id end def name - result = @path - result += File::SEPARATOR - result += sprintf("%0#{FILE_COUNTER_SIZE}d", @id) - result += '.' - result += @name + [ + @path, + File::SEPARATOR, + sprintf("%0#{FILE_COUNTER_SIZE}d", @id), + '.', + @name + ].join end end class CommandLog #:nodoc: @@ -361,10 +363,10 @@ end private def delete_log_files - names = Dir.glob(@directory_name + File::SEPARATOR + "*.command_log") + names = Dir.glob("#{@directory_name}#{File::SEPARATOR}*.command_log") names.each do |name| name.untaint File.delete(name) end end