Module: Persist
- Defined in:
- lib/scout/persist.rb,
lib/scout/persist/serialize.rb
Constant Summary collapse
- MEMORY_CACHE =
{}
- CONNECTIONS =
{}
- TRUE_STRINGS =
Set.new ["true", "True", "TRUE", "t", "T", "1", "yes", "Yes", "YES", "y", "Y", "ON", "on"]
- SERIALIZER =
:json
- MEMORY =
{}
Class Attribute Summary collapse
-
.cache_dir ⇒ Object
Returns the value of attribute cache_dir.
-
.load_drivers ⇒ Object
Returns the value of attribute load_drivers.
- .lock_dir ⇒ Object
-
.save_drivers ⇒ Object
Returns the value of attribute save_drivers.
Class Method Summary collapse
- .deserialize(serialized, type) ⇒ Object
- .load(file, type = :serializer) ⇒ Object
- .memory(name, options = {}, &block) ⇒ Object
- .persist(name, type = :serializer, options = {}, &block) ⇒ Object
- .persistence_path(name, options = {}) ⇒ Object
- .save(content, file, type = :serializer) ⇒ Object
- .serialize(content, type) ⇒ Object
Class Attribute Details
.cache_dir ⇒ Object
Returns the value of attribute cache_dir.
7 8 9 |
# File 'lib/scout/persist.rb', line 7 def cache_dir @cache_dir end |
.load_drivers ⇒ Object
Returns the value of attribute load_drivers.
10 11 12 |
# File 'lib/scout/persist/serialize.rb', line 10 def load_drivers @load_drivers end |
.lock_dir ⇒ Object
16 17 18 |
# File 'lib/scout/persist.rb', line 16 def lock_dir @lock_dir ||= Path.setup("tmp/persist_locks").find end |
.save_drivers ⇒ Object
Returns the value of attribute save_drivers.
10 11 12 |
# File 'lib/scout/persist/serialize.rb', line 10 def save_drivers @save_drivers end |
Class Method Details
.deserialize(serialized, type) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/scout/persist/serialize.rb', line 47 def self.deserialize(serialized, type) type = type.to_sym if String === type type = SERIALIZER if type == :serializer case type when nil, :string, :text, :file, :stream, :select, :folder serialized when :path Path.setup(serialized.strip) when :integer serialized.to_i when :float serialized.to_f when :boolean TRUE_STRINGS.include? serialized.strip when :array serialized.split("\n") when :yaml YAML.parse(serialized) when :json JSON.parse(serialized) when :marshal Marshal.load(serialized) else if m = type.to_s.match(/(.*)_array/) type = m[1].to_sym new_content = serialized.split("\n") new_content.collect{|c| deserialize(c, type) } else raise "Persist does not know #{Log.fingerprint type}" end end end |
.load(file, type = :serializer) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/scout/persist/serialize.rb', line 118 def self.load(file, type = :serializer) file = file.find if Path === file type = :serializer if type.nil? type = type.to_sym if String === type type = SERIALIZER if type == :serializer type = MEMORY if type == :memory return unless Hash === type || Open.exist?(file) Log.debug "Load #{Log.fingerprint type} on #{file}" if load_drivers[type] return load_drivers[type].call(file) end case type when :binary Open.read(file, :mode => 'rb') when :yaml Open.yaml(file) when :json Open.json(file) when :marshal, :serializer Open.marshal(file) when :stream Open.open(file) when :file value = Open.read(file) value.sub!(/^\./, File.dirname(file)) if value.start_with?("./") value when :file_array Open.read(file).split("\n").collect do |f| f.sub!(/^\./, File.dirname(file)) if f.start_with?("./") f end when Hash type[file] else deserialize(Open.read(file), type) end end |
.memory(name, options = {}, &block) ⇒ Object
99 100 101 102 |
# File 'lib/scout/persist.rb', line 99 def self.memory(name, = {}, &block) [:persist_path] ||= [:path] ||= [name, [:key]].compact * ":" self.persist(name, :memory, , &block) end |
.persist(name, type = :serializer, options = {}, &block) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/scout/persist.rb', line 31 def self.persist(name, type = :serializer, = {}, &block) = IndiferentHash.pull_keys , :persist return yield if FalseClass === [:persist] file = [:path] || [:path] || persistence_path(name, ) if type == :memory repo = [:memory] || [:repo] || MEMORY_CACHE repo[file] ||= yield return repo[file] end update = [:update] || [:update] update = Open.mtime(update) if Path === update update = Open.mtime(file) >= update ? false : true if Time === update lockfile = [:lockfile] || [:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir}) Open.lock lockfile do |lock| if Open.exist?(file) && ! update Persist.load(file, type) else begin file = file.find if Path === file return yield(file) if block.arity == 1 res = yield if res.nil? return Persist.load(file, type) end Open.rm(file) if IO === res || StringIO === res tee_copies = [:tee_copies] || 1 main, *copies = Open.tee_stream_thread_multiple res, tee_copies + 1 main.lock = lock t = Thread.new do Thread.current.report_on_exception = false Thread.current["name"] = "file saver: " + file Open.sensible_write(file, main) end Thread.pass until t["name"] copies.each_with_index do |copy,i| next_stream = copies[i+1] if copies.length > i ConcurrentStream.setup copy, :threads => t, :filename => file, :autojoin => true, :next => next_stream end res = copies.first raise KeepLocked.new(res) else pres = Persist.save(res, file, type) res = pres unless pres.nil? end rescue Exception Thread.handle_interrupt(Exception => :never) do if Open.exist?(file) Log.debug "Failed persistence #{file} - erasing" Open.rm file else Log.debug "Failed persistence #{file}" end end raise $! unless [:canfail] end res end end end |
.persistence_path(name, options = {}) ⇒ Object
21 22 23 24 25 26 27 |
# File 'lib/scout/persist.rb', line 21 def self.persistence_path(name, = {}) = IndiferentHash.add_defaults , :dir => Persist.cache_dir = IndiferentHash.pull_keys , :other name = name.filename if name.respond_to?(:filename) && name.filename = {} TmpFile.tmp_for_file(name, .merge(), ) end |
.save(content, file, type = :serializer) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/scout/persist/serialize.rb', line 82 def self.save(content, file, type = :serializer) type = :serializer if type.nil? type = type.to_sym if String === type type = SERIALIZER if type == :serializer type = MEMORY if type == :memory return if content.nil? type = MEMORY if type == :memory type = :serializer if type.nil? if Hash === type type[file] = content return end Log.debug "Save #{Log.fingerprint type} on #{file}" if save_drivers[type] if save_drivers[type].arity == 1 return Open.sensible_write(file, save_drivers[type].call(content)) else return save_drivers[type].call(file, content) end end if type == :binary content.force_encoding("ASCII-8BIT") if content.respond_to? :force_encoding Open.open(file, :mode => 'wb') do |f| f.puts content end content else serialized = serialize(content, type) Open.sensible_write(file, serialized, :force => true) return nil end end |
.serialize(content, type) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/scout/persist/serialize.rb', line 19 def self.serialize(content, type) type = type.to_sym if String === type type = SERIALIZER if type == :serializer case type when nil, :string, :text, :integer, :float, :boolean, :file, :path, :select, :folder, :binary if IO === content || StringIO === content content.read else content.to_s end when :array content * "\n" when :yaml content.to_yaml when :json content.to_json when :marshal Marshal.dump(content) else if m = type.to_s.match(/(.*)_array/) type = m[1].to_sym content.collect{|c| serialize(c, type) } * "\n" else raise "Persist does not know #{Log.fingerprint type}" end end end |