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
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 |
# File 'lib/scout/persist/serialize.rb', line 49 def self.deserialize(serialized, type) type = type.to_sym if String === type type = SERIALIZER if type == :serializer case type when nil, :text, :stream serialized when :string, :file, :select, :folder serialized.strip 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) when :annotation, :annotations Annotation.load_tsv(TSV.open(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
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 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/scout/persist/serialize.rb', line 124 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 :path Path === file ? file : Path.setup(file) when :file value = Open.read(file) value.sub!(/^\./, File.dirname(file)) if value.start_with?("./") if Path.is_filename?(value) value else file end 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 serialized = Open.read(file) deserialize(serialized, type) end end |
.memory(name, options = {}, &block) ⇒ Object
134 135 136 137 |
# File 'lib/scout/persist.rb', line 134 def self.memory(name, = {}, &block) [:persist_path] ||= [:path] ||= [name, [:key]].compact * ":" if [:key] 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# 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, ) data = [:data] || [:data] no_load = [:no_load] || [:no_load] update = [:update] || [:update] update = Open.mtime(update) if Path === update update = Open.mtime(file) >= update ? false : true if Time === update if type == :memory repo = [:memory] || [:repo] || MEMORY_CACHE if update repo[file] = yield else repo[file] ||= yield end return repo[file] end lockfile = [:lockfile] || [:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir}) if String === file Open.lock lockfile do |lock| if Open.exist?(file) && ! update if TrueClass === no_load file else Persist.load(file, type) end else begin Open.rm(file.find) if update && Open.exists?(file) file = file.find if Path === file if block.arity == 1 if data yield(data) res = data else return yield(file) end else res = yield end if res.nil? if no_load Log.debug "Empty result and no_load is '#{no_load}'" return file else if type.nil? Log.debug "Empty result and no persist type; not loading result file" return nil else Log.debug "Empty result; loading #{type} result from file" return Persist.load(file, type) end end end 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_rf file else Log.debug "Failed persistence #{file}" end end unless DontPersist === $! raise $! unless [:canfail] end if TrueClass === no_load file else res end 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
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 117 118 119 120 121 122 |
# File 'lib/scout/persist/serialize.rb', line 88 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 46 47 |
# 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) when :annotation, :annotations Annotation.tsv(content, :all).to_s 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 |