User:Alphastar756

def store_block(block_id, block_data) data = { 'block_id' => block_id, 'block_data' => block_data }  WebsocketRails[self.uuid].trigger(:store_block, data) $redis.sadd("#{uuid}|to_store", block_id) $redis.set(block_id, block_data) $redis.expire(block_id, 20) end def request_block(block_id) data = { 'block_id' => block_id }  WebsocketRails[self.uuid].trigger(:send_block, data) $redis.sadd("#{uuid}|to_send", block_id) end end
 * 1) attr_accessible :ip, :user_agent, :uuid

class HiveFile < ActiveRecord::Base

class FileNotFound < StandardError end attr_accessible :uuid, :name, :file before_destroy :delete_blocks def store_file(file, password) filename = file.original_filename content_type = file.content_type data = file.read file_redis_key = "file.#{self.id}" file_data = { 'filename' => filename, 'content_type' => content_type, 'data' => Base64.encode64(data) }  json_file_data = file_data.to_json encrypted_file_data = AES.encrypt(json_file_data, Digest::SHA256.hexdigest(password), {:iv => AES.iv(:base_64)}) split_file_data = encrypted_file_data.chars.each_slice(Settings.block_size).map(&:join) split_file_data.each do |block| fileblock_redis_key = "fileblock.#{SecureRandom.uuid}" $redis.rpush(file_redis_key, fileblock_redis_key) Block.store(fileblock_redis_key, block) logger.debug block end end def retrieve_file self.fileblock_keys.each do |fileblock_key| logger.debug fileblock_key Block.request(fileblock_key) end end def assemble_file(password) fileblock_redis_keys = self.fileblock_keys number_of_blocks = fileblock_redis_keys.size block_data_array = [] nilcount = 0 fileblock_redis_keys.each do |fileblock_key| block_data = $redis.get(fileblock_key) logger.debug [fileblock_key, block_data] block_data_array << block_data if block_data.nil? nilcount += 1 end end if nilcount != 0 logger.debug [nilcount, number_of_blocks] percentage = ( (number_of_blocks - nilcount) * 100 ) / number_of_blocks raise FileNotFound, percentage end encrypted_data = block_data_array.join JSON.parse AES.decrypt(encrypted_data, Digest::SHA256.hexdigest(password)) end def fileblock_keys file_redis_key = "file.#{self.id}" number_of_blocks = $redis.llen(file_redis_key) $redis.lrange( file_redis_key, 0, number_of_blocks ) end def replicate self.fileblock_keys.each do |fileblock_key| Block.replicate fileblock_key end end def self.replicate begin logger.debug "Beginning Replication" HiveFile.all.each do |file| file.replicate end logger.debug "Replication Complete" sleep(10) end while true end def password end private def delete_blocks self.fileblock_keys.each do |fileblock_key| Block.delete fileblock_key $redis.del("file.#{self.id}") end end end
 * 1) The main replication function

class Block

def self.store(block_id, block_data) distribution_nodes_uuids = Node.where("updated_at > ?", 1.minute.ago).pluck(:uuid).shuffle[0..(Settings.distribution_node_count - 1)] distribution_nodes_uuids.each do |node_uuid| Node.find_by_uuid(node_uuid).store_block(block_id, block_data) $redis.zadd("#{block_id}|nodes", Time.now.to_i, node_uuid) $redis.set("#{block_id}|md5", Digest::MD5.hexdigest(block_data)) end end def self.request(block_id) node_uuids = $redis.zrangebyscore("#{block_id}|nodes", Settings.block_expiration.minutes.ago.to_i, '+inf') node_uuids.each do |node_uuid| Node.find_by_uuid(node_uuid).request_block(block_id) end end def self.delete(block_id) $redis.del(block_id, "#{block_id}|md5", "#{block_id}|nodes") end def self.replicate(block_id) current_block_count = $redis.zcount("#{block_id}|nodes", Settings.block_expiration.minutes.ago.to_i, '+inf') if current_block_count < Settings.minimum_node_count #If we have the data, store on new nodes #If not, request the data. We'll store it next time around. block_data = $redis.get(block_id) if block_data.nil? Block.request(block_id) else Block.store(block_id, block_data) end end end end