Class: FC::Item
Instance Attribute Summary
Attributes inherited from DbBase
#additional_fields, #database_fields, #id
Class Method Summary collapse
-
.create_from_local(local_path, item_name, policy, options = {}, &block) ⇒ Object
Create item by local path.
Instance Method Summary collapse
- #copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) ⇒ Object
- #dir? ⇒ Boolean
- #get_available_storages ⇒ Object
- #get_item_storages ⇒ Object
-
#immediate_delete ⇒ Object
mark item and his items_storages for immediate delete.
- #item_storage_status_set(item_storage, status) ⇒ Object
- #make_item_storage(storage, status = 'new') ⇒ Object
-
#mark_deleted ⇒ Object
mark item and his items_storages for deferred delete real delete after policy.delete_deferred_time.
- #url ⇒ Object
- #urls ⇒ Object
Methods inherited from DbBase
apply!, create_from_fiels, #delete, #dump, find, #initialize, #load, #reload, #save, set_table, where
Constructor Details
This class inherits a constructor from FC::DbBase
Class Method Details
.create_from_local(local_path, item_name, policy, options = {}, &block) ⇒ Object
Create item by local path. Additional options:
:replace=true - replace item if it exists
:remove_local=true - delete local_path file/dir after add
:additional_fields - hash of additional FC:Item fields
:no_md5 - don't use md5
:speed_limit - limit copy speed
:force_local_storage
If item_name is part of local_path it processed as inplace - local_path is valid path to the item for policy
18 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 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 |
# File 'lib/fc/item.rb', line 18 def self.create_from_local(local_path, item_name, policy, ={}, &block) raise 'Path not exists' unless File.exists?(local_path) raise 'Policy is not FC::Policy' unless policy.instance_of?(FC::Policy) item_params = .merge({ :name => item_name.to_s.gsub('//', '/').sub(/\/$/, '').sub(/^\//, '').strip, :policy_id => policy.id, :dir => File.directory?(local_path), :size => FC::Storage.new(:host => FC::Storage.curr_host).file_size(local_path), :md5 => nil }) item_params[:md5] = FC::Storage.new( :host => FC::Storage.curr_host ).md5_sum(local_path) unless item_params[:no_md5] item_params.delete(:replace) item_params.delete(:remove_local) item_params.delete(:not_local) item_params.delete(:no_md5) item_params.delete(:speed_limit) item_params.delete(:force_local_storage) raise 'Name is empty' if item_params[:name].empty? raise 'Zero size path' if item_params[:size] == 0 if local_path.include?(item_name) && ![:not_local] if [:force_local_storage] storage = [:force_local_storage] if local_path.index(storage.path) != 0 || local_path.sub(storage.path, '').sub(/\/$/, '').sub(/^\//, '') != item_params[:name] FC::Error.raise "force_local_storage #{storage.name} is not valid path for local path ##{local_path}" end else storage = policy.get_create_storages.detect do |s| s.host == FC::Storage.curr_host && local_path.index(s.path) == 0 && local_path.sub(s.path, '').sub(/\/$/, '').sub(/^\//, '') == item_params[:name] end FC::Error.raise "local_path #{local_path} is not valid path for policy ##{policy.id}" unless storage end end # new item? item = FC::Item.where('name=? AND policy_id=?', item_params[:name], policy.id).first if item if [:replace] || storage # replace all fields item_params.each{|key, val| item.send("#{key}=", val)} else FC::Error.raise 'Item already exists', :item_id => item.id end else item = FC::Item.new(item_params) end item.save if storage item_storage = item.make_item_storage(storage, 'ready') item.reload else if item.copies.to_i > 0 # find storage in item.item_storages storages_names = item.get_item_storages.select{|s| s.status == 'ready'}.map(&:storage_name) storage = FC::Storage.select_proper_storage_for_create(policy.get_create_storages, item.size) do |storages| storages.select{|s| storages_names.detect(s.name)} end end if block_given? storage ||= FC::Storage.select_proper_storage_for_create(policy.get_create_storages, item.size, &block) else storage ||= policy.get_proper_storage_for_create(item.size, local_path) end FC::Error.raise 'No available storage', :item_id => item.id unless storage # mark delete item_storages on replace FC::DB.query("UPDATE #{FC::ItemStorage.table_name} SET status='delete' WHERE item_id = #{item.id} AND storage_name <> '#{storage.name}'") if [:replace] item_storage = item.make_item_storage(storage) item.copy_item_storage(local_path, storage, item_storage, [:remove_local], [:speed_limit]) end return item end |
Instance Method Details
#copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) ⇒ Object
111 112 113 114 115 116 117 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 |
# File 'lib/fc/item.rb', line 111 def copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) begin if src.instance_of?(FC::Storage) src.copy_to_local(name, "#{storage.path}#{name}", speed_limit) else storage.copy_path(src, name, remove_local, speed_limit) end md5_on_storage = storage.md5_sum(name) if md5 rescue Exception => e item_storage_status_set(item_storage, 'error') FC::Error.raise "Copy error: #{e.}", :item_id => id, :item_storage_id => item_storage.id else begin item_storage.reload rescue Exception => e FC::Error.raise "After copy error: #{e.}", :item_id => id, :item_storage_id => item_storage.id else if md5 && md5_on_storage != md5 item_storage_status_set(item_storage, 'error') FC::Error.raise "Check md5 after copy error", :item_id => id, :item_storage_id => item_storage.id else item_storage_status_set(item_storage, 'ready') if remove_local && !src.instance_of?(FC::Storage) && File.exists?(src) if File.directory?(src) FileUtils.rm_r(src) else File.delete(src) end end end end end end |
#dir? ⇒ Boolean
168 169 170 |
# File 'lib/fc/item.rb', line 168 def dir? dir.to_i == 1 end |
#get_available_storages ⇒ Object
176 177 178 179 180 181 182 183 184 |
# File 'lib/fc/item.rb', line 176 def get_available_storages r = FC::DB.query("SELECT st.* FROM #{FC::Storage.table_name} as st, #{FC::ItemStorage.table_name} as ist WHERE ist.item_id = #{id} AND ist.status='ready' AND ist.storage_name = st.name") istorages = r.map { |data| FC::Storage.create_from_fiels(data) } .select { |storage| storage.up? && storage.url_weight.to_i >= 0 } http_up_storages = istorages.select(&:http_up?) istorages = http_up_storages if http_up_storages.any? istorages end |
#get_item_storages ⇒ Object
172 173 174 |
# File 'lib/fc/item.rb', line 172 def get_item_storages FC::ItemStorage.where("item_id = #{id}") end |
#immediate_delete ⇒ Object
mark item and his items_storages for immediate delete
162 163 164 165 166 |
# File 'lib/fc/item.rb', line 162 def immediate_delete FC::DB.query("UPDATE #{FC::ItemStorage.table_name} SET status='delete' WHERE item_id = #{id}") self.status = 'delete' save end |
#item_storage_status_set(item_storage, status) ⇒ Object
145 146 147 148 149 150 151 152 |
# File 'lib/fc/item.rb', line 145 def item_storage_status_set(item_storage, status) reload marked_for_delete = self.status == 'deferred_delete' item_storage.status = status item_storage.save reload mark_deleted if marked_for_delete end |
#make_item_storage(storage, status = 'new') ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/fc/item.rb', line 97 def make_item_storage(storage, status = 'new') # new storage_item? item_storage = FC::ItemStorage.where('item_id=? AND storage_name=?', id, storage.name).first if item_storage item_storage.delete storage.size = storage.size.to_i - size.to_i end item_storage = FC::ItemStorage.new({:item_id => id, :storage_name => storage.name, :status => status}) item_storage.save storage.size = storage.size.to_i + size.to_i item_storage end |
#mark_deleted ⇒ Object
mark item and his items_storages for deferred delete real delete after policy.delete_deferred_time
156 157 158 159 |
# File 'lib/fc/item.rb', line 156 def mark_deleted self.status = 'deferred_delete' save end |
#url ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/fc/item.rb', line 190 def url available_storages = get_available_storages() # sort by random(url_weight) best_storage = available_storages.map { |storage| [storage, Kernel.rand(storage.url_weight.to_i * 100)] } .sort_by { |a| a[1] } .map { |el| el[0] } .last best_storage = available_storages.sample unless best_storage raise "URL find - no avable storage for item #{id}" unless best_storage File.join(best_storage.url, name) end |
#urls ⇒ Object
186 187 188 |
# File 'lib/fc/item.rb', line 186 def urls get_available_storages.map { |storage| File.join(storage.url, name) } end |