filecluster 0.4.22 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4874f465a9a024770d5d40cb01e2749c1e45782
4
- data.tar.gz: 53e2d183d39749cbaee8dbef14b93a2283b9a514
3
+ metadata.gz: 0a47f34292388667e2040dfa0cee212503869229
4
+ data.tar.gz: d69557e79d7ba8365d9aa48c58e678e0ddf6a23e
5
5
  SHA512:
6
- metadata.gz: 36c3b885ff48bd21933587dae98c6faf865c3b194eaad4908ef624dbed71f359216eae1c2d01528c5b8a38ac490bac9d54296d9e827ff295fc355de2af86a790
7
- data.tar.gz: 5619eb4c21e89d16cb0d518fd4f16000c745f30895288f82169e5d60dd40132ab3021f41e5249b494d33f138b237dcd1db6ed9590bd4959d5cfe8e0fd002cf07
6
+ metadata.gz: 83ea94afcc5c96f8066f71310447744685839dbd5ef657928a5212519f0404b9ea4f1036a96ed922918b77cdfc2c6a5630e64a6c6b04c90bac6ae91941182f9b
7
+ data.tar.gz: 74aaf8eb6378e07202d6bc10a9d94c66d0df54e7290af322fac9836f0ac30e43a3ffd5b63cfb8831251ae5a0d3070fc00dfb78de4f4db9635e0293091c03197d
data/bin/fc-daemon CHANGED
@@ -25,7 +25,7 @@ $update_tasks_thread = nil
25
25
  $run_tasks_thread = nil
26
26
 
27
27
  args = ARGV.clone
28
- default_db_config = File.expand_path(File.dirname(__FILE__))+'/db.yml'
28
+ default_db_config = FC::DB.options_yml_path
29
29
  descriptions = {
30
30
  :config => {:short => 'c', :full => 'config', :default => default_db_config, :text => "path to db.yml file, default #{default_db_config}"},
31
31
  :log_level => {:short => 'l', :full => 'log_level', :default => 'info', :text => 'log level (fatal, error, warn, info or debug), default info'},
data/bin/fc-manage CHANGED
@@ -8,7 +8,7 @@ require 'filecluster'
8
8
  require 'utils'
9
9
  require 'manage'
10
10
 
11
- default_db_config = File.expand_path(File.dirname(__FILE__))+'/db.yml'
11
+ default_db_config = FC::DB.options_yml_path
12
12
  descriptions = {
13
13
  :config => {:short => 'c', :full => 'config', :default => default_db_config, :text => "path to db.yml file, default #{default_db_config}"},
14
14
  :curr_host => {:short => 'h', :full => 'host', :default => FC::Storage.curr_host, :text => "Host for storages, default #{FC::Storage.curr_host}"}
data/bin/fc-setup-db CHANGED
@@ -27,7 +27,7 @@ options = option_parser_init(descriptions, desc)
27
27
  trap("INT", proc {exit})
28
28
 
29
29
  if !options[:__keys][:host] && !options[:__keys][:database] && !options[:__keys][:username] && !options[:__keys][:password] && !options[:__keys][:port] && !options[:__keys][:prefix]
30
- default_db_config = File.expand_path(File.dirname(__FILE__))+'/db.yml'
30
+ default_db_config = FC::DB.options_yml_path
31
31
  if File.exists?(default_db_config)
32
32
  db_options = Psych.load(File.read(default_db_config))
33
33
  options.merge!(db_options)
data/lib/fc/base.rb CHANGED
@@ -16,7 +16,7 @@ module FC
16
16
  end
17
17
 
18
18
  def self.table_name
19
- FC::DB.connect unless FC::DB.options
19
+ FC::DB.connect! unless FC::DB.options
20
20
  "#{FC::DB.prefix}#{@table_name}"
21
21
  end
22
22
 
data/lib/fc/db.rb CHANGED
@@ -1,8 +1,15 @@
1
1
  require 'mysql2'
2
+ require 'psych'
2
3
 
3
4
  module FC
4
5
  module DB
5
- class << self; attr_accessor :options, :prefix, :err_counter end
6
+ class << self
7
+ attr_accessor :options, :prefix, :err_counter, :no_active_record, :connect_block, :logger
8
+ end
9
+
10
+ def self.options_yml_path
11
+ File.expand_path(File.dirname(__FILE__) + '../../../bin/db.yml')
12
+ end
6
13
 
7
14
  def self.connect_by_config(options)
8
15
  @options = options.clone
@@ -11,45 +18,67 @@ module FC
11
18
  @connects = {} unless @connects
12
19
  @connects[Thread.current.object_id] = Mysql2::Client.new(@options)
13
20
  end
14
-
15
- def self.connect(options = {})
16
- if !@options
17
- if options[:host] || options[:database] || options[:username] || options[:password] ||
18
- !defined?(ActiveRecord::Base) || !ActiveRecord::Base.connection
19
- self.connect_by_config(options)
20
- else
21
- if defined?(Octopus::Proxy) && ActiveRecord::Base.connection.is_a?(Octopus::Proxy)
22
- connection = ActiveRecord::Base.connection.select_connection.instance_variable_get(:@connection)
23
- else
24
- connection = ActiveRecord::Base.connection.instance_variable_get(:@connection)
25
- end
26
- @options = connection.query_options.clone
27
- @options.merge!(options)
28
- @prefix = @options[:prefix].to_s if @options[:prefix]
29
- @connects = {} unless @connects
30
- @connects[Thread.current.object_id] = connection
31
- end
21
+
22
+ def self.connect_by_yml(options = {})
23
+ db_options = Psych.load(File.read(options_yml_path))
24
+ connect_by_config(db_options.merge(options))
25
+ end
26
+
27
+ def self.connect_by_active_record(options = {})
28
+ if defined?(Octopus::Proxy) && ActiveRecord::Base.connection.is_a?(Octopus::Proxy)
29
+ connection = ActiveRecord::Base.connection.select_connection.instance_variable_get(:@connection)
32
30
  else
33
- @options.merge!(options)
31
+ connection = ActiveRecord::Base.connection.instance_variable_get(:@connection)
34
32
  end
35
- if @options[:multi_threads]
36
- @connects[Thread.current.object_id] ||= Mysql2::Client.new(@options)
33
+ @options = connection.query_options.clone
34
+ @options.merge!(options)
35
+ @prefix = @options[:prefix].to_s if @options[:prefix]
36
+ @connects = {} unless @connects
37
+ @connects[Thread.current.object_id] = connection
38
+ end
39
+
40
+ def self.lazy_connect(&block)
41
+ @connect_block = block
42
+ end
43
+
44
+ def self.connect_by_block(options = {})
45
+ connection = @connect_block.call
46
+ @options = connection.query_options.clone.merge(options)
47
+ @prefix = @options[:prefix].to_s if @options[:prefix]
48
+ @connects = {} unless @connects
49
+ @connects[Thread.current.object_id] = connection
50
+ @connect_block = nil
51
+ end
52
+
53
+ def self.connect
54
+ connect_by_block if @connect_block
55
+ return nil unless @options
56
+ connect_by_config(@options) if @options[:multi_threads] && !@connects[Thread.current.object_id]
57
+ if @options[:multi_threads]
58
+ @connects[Thread.current.object_id]
37
59
  else
38
- @connects.first[1]
60
+ @connects.first && @connects.first[1]
39
61
  end
40
62
  end
41
63
 
42
64
  def self.connect!(options = {})
43
- self.connect(options)
44
- end
45
-
46
- # deprecated!
47
- def self.connect=(connect, options = {})
48
- self.connect_by_config connect.query_options.merge(options).merge(:as => :hash)
65
+ close if @connects && @connects[Thread.current.object_id]
66
+ if @connect_block
67
+ connect_by_block(options)
68
+ elsif options[:host] || options[:database] || options[:username] || options[:password]
69
+ connect_by_config(options)
70
+ elsif @options
71
+ connect_by_config(@options.merge(options))
72
+ elsif !@no_active_record && defined?(ActiveRecord::Base) && ActiveRecord::Base.connection
73
+ connect_by_active_record(options)
74
+ else
75
+ connect_by_yml(options)
76
+ end
49
77
  end
50
- class << self
51
- extend Gem::Deprecate
52
- deprecate :connect=, :connect!, 2016, 01
78
+
79
+ def self.reconnect
80
+ close if connect
81
+ connect_by_config(@options)
53
82
  end
54
83
 
55
84
  def self.close
@@ -60,35 +89,42 @@ module FC
60
89
  end
61
90
  else
62
91
  @connects.first[1].close
92
+ @connects.clear
63
93
  end
64
94
  end
65
95
 
66
96
  # connect.query with deadlock solution
67
97
  def self.query(sql)
68
98
  raise 'Too many mysql errors' if FC::DB.err_counter && FC::DB.err_counter > 10
99
+ t1 = Time.new.to_f
69
100
  r = FC::DB.connect.query(sql)
101
+ t2 = Time.new.to_f
102
+ @logger.debug(format('FC SQL (%.1fms) %s', (t2 - t1) * 1000, sql)) if @logger
70
103
  FC::DB.err_counter = 0
71
- r = r.each(:as => :hash){} if r
104
+ r = r.each(:as => :hash) {} if r
72
105
  r
73
106
  rescue Mysql2::Error => e
74
107
  FC::DB.err_counter = FC::DB.err_counter.to_i + 1
75
108
  if e.message.match('Deadlock found when trying to get lock')
76
- puts "#{e.message} - retry"
109
+ msg = "#{e.message} - retry"
110
+ @logger ? @logger.error(msg) : puts(msg)
77
111
  sleep 0.1
78
- self.query(sql)
112
+ query(sql)
79
113
  elsif e.message.match('Lost connection to MySQL server during query')
80
- puts "#{e.message} - reconnect"
114
+ msg = "#{e.message} - reconnect"
115
+ @logger ? @logger.error(msg) : puts(msg)
81
116
  FC::DB.connect.ping
82
117
  sleep 0.1
83
- self.query(sql)
118
+ query(sql)
84
119
  elsif @options[:reconnect]
85
- puts "#{e.message} - reconnect"
86
- self.connect_by_config(@options)
87
- self.query(sql)
120
+ msg = "#{e.message} - reconnect"
121
+ @logger ? @logger.info(msg) : puts(msg)
122
+ reconnect
123
+ query(sql)
88
124
  else
89
125
  raise e
90
126
  end
91
- end
127
+ end
92
128
 
93
129
  def self.server_time
94
130
  FC::DB.query("SELECT UNIX_TIMESTAMP() as curr_time").first['curr_time'].to_i
data/lib/fc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FC
2
- VERSION = "0.4.22"
2
+ VERSION = '0.5.1'.freeze
3
3
  end
@@ -109,7 +109,7 @@ def storages_update_size
109
109
  print "Calc current size.. "
110
110
  size = storage.file_size('', true)
111
111
  storage.size = size
112
- FC::DB.connect
112
+ FC::DB.reconnect
113
113
  begin
114
114
  storage.save
115
115
  rescue Exception => e
@@ -244,7 +244,7 @@ def make_storages_sync(storage, make_delete, silent = false, no_reconnect = fals
244
244
  process_storage_dir_sync.call
245
245
 
246
246
  # rm delete_files
247
- FC::DB.connect unless no_reconnect
247
+ FC::DB.reconnect unless no_reconnect
248
248
  if make_delete
249
249
  puts "Deleting files" unless silent
250
250
  delete_files.each do |f|
data/test/daemon_test.rb CHANGED
@@ -77,6 +77,7 @@ class DaemonTest < Test::Unit::TestCase
77
77
  end
78
78
 
79
79
  should "daemon_all" do
80
+ puts 'Start' if @debug
80
81
  @@storages.each {|storage| storage.reload}
81
82
  assert @@storages[0].up?, "Storage #{@@storages[0].name} down"
82
83
  assert @@storages[1].up?, "Storage #{@@storages[1].name} down"
@@ -90,9 +91,10 @@ class DaemonTest < Test::Unit::TestCase
90
91
 
91
92
  @@policy.copies = 3
92
93
  @@policy.save
93
- sleep 2
94
-
94
+
95
95
  # wait for copy
96
+ sleep 2
97
+ puts 'Check copy' if @debug
96
98
  [1, 2, 3].each do |i|
97
99
  ['b', 'c'].each do |j|
98
100
  assert_equal `du -sb /tmp/host1-sda/bla/bla/test$i 2>&1`.to_i, `du -sb /tmp/host$i-sd$j/bla/bla/test$i 2>&1`.to_i
@@ -105,7 +107,9 @@ class DaemonTest < Test::Unit::TestCase
105
107
  item_storage = FC::ItemStorage.where('item_id = ? AND storage_name = ?', @item1.id, 'host1-sdc').first
106
108
  item_storage.status = 'delete'
107
109
  item_storage.save
110
+
108
111
  sleep 2
112
+ puts 'Check delete' if @debug
109
113
  assert_equal 0, `du -sb /tmp/host1-sdc/bla/bla/test1 2>&1`.to_i
110
114
  assert_equal @@errors_count, FC::Error.where.count, "new errors in errors table"
111
115
 
@@ -118,6 +122,7 @@ class DaemonTest < Test::Unit::TestCase
118
122
  @item3.save
119
123
 
120
124
  sleep 6
125
+ puts 'Check mark_deleted' if @debug
121
126
  assert_raise(RuntimeError, "Item not deleted after mark_deleted") {@item1.reload}
122
127
  assert_equal 0, FC::ItemStorage.where('item_id = ?', @item2.id).count, "ItemStorages not deleted after status='error'"
123
128
  @item3.reload
data/test/db_test.rb CHANGED
@@ -51,6 +51,61 @@ class DbTest < Test::Unit::TestCase
51
51
  @item_storage = @item_storages.first
52
52
  @item_storage2 = @item_storages[1]
53
53
  end
54
+
55
+ should 'sql logger' do
56
+ FC::DB.logger = mock
57
+ FC::DB.logger.expects(:debug).at_least_once
58
+ FC::DB.query 'SELECT 1'
59
+ FC::DB.logger = nil
60
+ end
61
+
62
+ should 'close, reconnect and connect_by_yml' do
63
+ db_config_file = File.expand_path(File.dirname(__FILE__)) + '/db_test.yml'
64
+ File.open(db_config_file, 'w') do |f|
65
+ f.write(FC::DB.options.to_yaml)
66
+ end
67
+
68
+ connect = FC::DB.connect
69
+ FC::DB.close
70
+ assert_false connect.ping, 'Mysql2 connect not closed after close call'
71
+ assert_nil FC::DB.connect, 'FC::DB.connect is not empty after close call'
72
+
73
+ FC::DB.stubs(:options_yml_path).returns(db_config_file)
74
+ FC::DB.connect_by_yml
75
+ assert_true FC::DB.connect.ping, 'Not connected after connect_by_yml'
76
+
77
+ FC::DB.close
78
+ FC::DB.reconnect
79
+ assert_true FC::DB.connect.ping, 'Not connected after reconnect'
80
+ end
81
+
82
+ should 'lazy_connect' do
83
+ FC::DB.close
84
+ FC::DB.lazy_connect do
85
+ Mysql2::Client.new(FC::DB.options)
86
+ end
87
+ FC::DB.connect!(:multi_threads => true)
88
+ assert_true FC::DB.connect.ping, 'Not connected after lazy_connect with Mysql2'
89
+ assert_true FC::DB.options[:multi_threads], 'Options from connect!(options) was not setted'
90
+
91
+ FC::DB.close
92
+ FC::DB.lazy_connect do
93
+ FC::DB.connect_by_config(FC::DB.options)
94
+ end
95
+ assert_true FC::DB.connect.ping, 'Not connected after lazy_connect with FC::DB.connect_by_config'
96
+ end
97
+
98
+ should 'multi threads' do
99
+ FC::DB.connect!(:multi_threads => true)
100
+ threads = Array.new(5) do
101
+ Thread.new do
102
+ assert_nothing_raised { FC::DB.query('select sleep(0.05)') }
103
+ end
104
+ end
105
+ threads.each(&:join)
106
+ assert_equal FC::DB.instance_variable_get(:@connects).keys.count, 6
107
+ FC::DB.connect!(:multi_threads => false)
108
+ end
54
109
 
55
110
  should "items" do
56
111
  assert @items.count > 0, 'Items not loaded'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filecluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.22
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - sh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-23 00:00:00.000000000 Z
11
+ date: 2016-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2