lib/zold/copies.rb in zold-0.13.43 vs lib/zold/copies.rb in zold-0.13.44
- old
+ new
@@ -19,20 +19,25 @@
# SOFTWARE.
require 'time'
require 'csv'
require_relative 'atomic_file'
+require_relative 'log'
# The list of copies.
# Author:: Yegor Bugayenko (yegor256@gmail.com)
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
# License:: MIT
module Zold
# All copies
class Copies
- def initialize(dir)
+ def initialize(dir, log: Log::Quiet.new)
+ raise 'Dir can\'t be nil' if dir.nil?
@dir = dir
+ raise 'Log can\'t be nil' if log.nil?
+ @log = log
+ @mutex = Mutex.new
end
def root
File.join(@dir, '..')
end
@@ -40,20 +45,31 @@
def to_s
File.basename(@dir)
end
def clean
- list = load
- list.reject! { |s| s[:time] < Time.now - 24 * 60 * 60 }
- save(list)
- Dir.new(@dir).select { |f| f =~ /^[0-9]+$/ }.each do |f|
- File.delete(File.join(@dir, f)) if list.find { |s| s[:name] == f }.nil?
+ @mutex.synchronize do
+ list = load
+ list.reject! { |s| s[:time] < Time.now - 24 * 60 * 60 }
+ save(list)
+ deleted = 0
+ Dir.new(@dir).select { |f| f =~ /^[0-9]+$/ }.each do |f|
+ next unless list.find { |s| s[:name] == f }.nil?
+ file = File.join(@dir, f)
+ size = File.size(file)
+ File.delete(file)
+ @log.debug("Copy ##{f} deleted: #{size}b")
+ deleted += 1
+ end
+ deleted
end
end
def remove(host, port)
- save(load.reject { |s| s[:host] == host && s[:port] == port })
+ @mutex.synchronize do
+ save(load.reject { |s| s[:host] == host && s[:port] == port })
+ end
end
# Returns the name of the copy
def add(content, host, port, score, time = Time.now)
raise "Content can't be empty" if content.empty?
@@ -61,50 +77,52 @@
raise "TCP port can't be negative: #{port}" if port < 0
raise 'Time must be of type Time' unless time.is_a?(Time)
raise "Time must be in the past: #{time}" if time > Time.now
raise 'Score must be Integer' unless score.is_a?(Integer)
raise "Score can't be negative: #{score}" if score < 0
- FileUtils.mkdir_p(@dir)
- list = load
- target = list.find do |s|
- f = File.join(@dir, s[:name])
- File.exist?(f) && AtomicFile.new(f).read == content
+ @mutex.synchronize do
+ FileUtils.mkdir_p(@dir)
+ list = load
+ target = list.find do |s|
+ f = File.join(@dir, s[:name])
+ File.exist?(f) && AtomicFile.new(f).read == content
+ end
+ if target.nil?
+ max = Dir.new(@dir)
+ .select { |f| f =~ /^[0-9]+$/ }
+ .map(&:to_i)
+ .max
+ max = 0 if max.nil?
+ name = (max + 1).to_s
+ AtomicFile.new(File.join(@dir, name)).write(content)
+ else
+ name = target[:name]
+ end
+ list.reject! { |s| s[:host] == host && s[:port] == port }
+ list << {
+ name: name,
+ host: host,
+ port: port,
+ score: score,
+ time: time
+ }
+ save(list)
+ name
end
- if target.nil?
- max = Dir.new(@dir)
- .select { |f| f =~ /^[0-9]+$/ }
- .map(&:to_i)
- .max
- max = 0 if max.nil?
- name = (max + 1).to_s
- AtomicFile.new(File.join(@dir, name)).write(content)
- else
- name = target[:name]
- end
- list.reject! { |s| s[:host] == host && s[:port] == port }
- list << {
- name: name,
- host: host,
- port: port,
- score: score,
- time: time
- }
- save(list)
- name
end
def all
- load.group_by { |s| s[:name] }.map do |name, scores|
- {
- name: name,
- host: scores[0][:host],
- port: scores[0][:port],
- path: File.join(@dir, name),
- score: scores.select { |s| s[:time] > Time.now - 24 * 60 * 60 }
- .map { |s| s[:score] }
- .inject(&:+) || 0
- }
- end.select { |c| File.exist?(c[:path]) }
+ @mutex.synchronize do
+ load.group_by { |s| s[:name] }.map do |name, scores|
+ {
+ name: name,
+ path: File.join(@dir, name),
+ score: scores.select { |s| s[:time] > Time.now - 24 * 60 * 60 }
+ .map { |s| s[:score] }
+ .inject(&:+) || 0
+ }
+ end.select { |c| File.exist?(c[:path]) }
+ end
end
private
def load