rbbt-util 5.13.31 → 5.13.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22e6c0ab1705d1790142288b6bc9943665830554
4
- data.tar.gz: 7873db2daa7dafc6ee9b8e1ba9ac12191c8c5d8b
3
+ metadata.gz: 03d6c0cd25cb674bc5fb28731e6c936d32a8468c
4
+ data.tar.gz: 0a8c5ba0281f806e9d8712e527b011bae576bacf
5
5
  SHA512:
6
- metadata.gz: 07dee96dd2fabee74fbf1ae2852a657f16f30f16c818c092ebd352a6769b080155881a255a48098ebcf749efa95abb13cd9e9da82cecdbdec1a0e415be0c1940
7
- data.tar.gz: 547fd0998e00974bc5ecd8bc3ba1b8a98db556cfb48d8c2e2fb0e327eeaaa9af6023112d3ebfdde613911cc459d54c23c60221dc5f55ce6ac40e288d7b33a027
6
+ metadata.gz: 24555145911d44367c1b9ddfe30c96b7e205811b9838508e68faebeb07da384b4fdc1d9bed59a221f97b00e51ba8ea816fccbb7c26517de79433e3306a9e8fbc
7
+ data.tar.gz: 6b275e80ce80ac94a8067c8f255c50d718fab0717934ff46e5354640951d4f94ae5361cb92d429b2cd14ba3edaea35f5dd26e9748eb4021a53bd1c33f576592b
data/bin/rbbt CHANGED
@@ -42,8 +42,19 @@ $ rbbt <command> <subcommand> ... -a --arg1 --arg2='value' --arg3 'another-value
42
42
  --nocolor #{Log.color :yellow, "Disable colored output"}
43
43
  --nobar #{Log.color :yellow, "Disable progress report"}
44
44
  --locate_file #{Log.color :yellow, "Report the location of the script instead of executing it"}
45
+ --dump_mem* #{Log.color :yellow, "Dump strings in memory each second into file"}
46
+ --no_lock_id #{Log.color :yellow, "Do not track lockfiles with ids (for high-througput and high-concurrency"}
45
47
  EOF
46
48
 
49
+ if options.delete(:no_lock_id)
50
+ Misc.use_lock_id = false
51
+ end
52
+
53
+ if mem_dump = options.delete(:dump_mem)
54
+ require 'rbbt/monitor'
55
+ Rbbt.dump_memory(mem_dump, Symbol)
56
+ end
57
+
47
58
  if options.delete :nobar
48
59
  ENV["RBBT_NO_PROGRESS"] = "true"
49
60
  end
data/lib/rbbt/monitor.rb CHANGED
@@ -5,28 +5,170 @@ module Rbbt
5
5
  LOCK_DIRS = Rbbt.share.find_all + Rbbt.var.cache.persistence.find_all + Rbbt.var.jobs.find_all +
6
6
  Rbbt.tmp.tsv_open_locks.find_all + Rbbt.tmp.persist_locks.find_all
7
7
 
8
+ SENSIBLE_WRITE_DIRS = Misc.sensiblewrite_dir.find_all
9
+
10
+ PERSIST_DIRS = Rbbt.share.find_all + Rbbt.var.cache.persistence.find_all
11
+
12
+ JOB_DIRS = Rbbt.var.jobs.find_all
13
+
14
+ def self.dump_memory(file, obj = nil)
15
+ Log.info "Dumping #{obj} objects into #{ file }"
16
+ Thread.new do
17
+ while true
18
+ Open.write(file) do |f|
19
+ Thread.exclusive do
20
+ GC.start
21
+ ObjectSpace.each_object(obj) do |o|
22
+ f.puts "---"
23
+ f.puts(String === o ? o : o.inspect)
24
+ end
25
+ end
26
+ end
27
+ FileUtils.cp file, file + '.save'
28
+ sleep 3
29
+ end
30
+ end
31
+ end
32
+
33
+ def self.file_time(file)
34
+ ctime = File.ctime file
35
+ atime = File.atime file
36
+ elapsed = Time.now - ctime
37
+ {:ctime => ctime, :atime => atime, :elapsed => elapsed}
38
+ end
39
+
40
+ #{{{ LOCKS
41
+
8
42
  def self.locks(dirs = LOCK_DIRS)
9
43
  dirs.collect do |dir|
10
- dir.glob("**/*.lock")
11
- end.flatten
44
+ next unless Open.exists? dir
45
+ `find "#{ dir }" -name "*.lock"`.split "\n"
46
+ end.compact.flatten
12
47
  end
13
48
 
14
- SENSIBLE_WRITE_DIRS = Misc.sensiblewrite_dir.find_all
49
+ def self.lock_info(dirs = LOCK_DIRS)
50
+ lock_info = {}
51
+ locks(dirs).each do |f|
52
+ begin
53
+ i = file_time(f)
54
+ if File.size(f) > 0
55
+ info = Open.open(f) do |s|
56
+ YAML.load(s)
57
+ end
58
+ i[:pid] = info[:pid]
59
+ i[:ppid] = info[:ppid]
60
+ end
61
+ lock_info[f] = i
62
+ rescue
63
+ Log.exception $!
64
+ end
65
+ end
66
+ lock_info
67
+ end
68
+
69
+ #{{{ SENSIBLE WRITES
70
+
15
71
  def self.sensiblewrites(dirs = SENSIBLE_WRITE_DIRS)
16
72
  dirs.collect do |dir|
17
- dir.glob("**/*").reject{|f| f =~ /\.lock$/ }
18
- end.flatten
73
+ next unless Open.exists? dir
74
+ `find "#{ dir }" -not -name "*.lock" -not -type d`.split "\n"
75
+ end.compact.flatten
19
76
  end
20
77
 
21
- PERSIST_DIRS = Rbbt.share.find_all + Rbbt.var.cache.persistence.find_all
78
+ def self.sensiblewrite_info(dirs = SENSIBLE_WRITE_DIRS)
79
+ info = {}
80
+ sensiblewrites(dirs).each do |f|
81
+ begin
82
+ i = file_time(f)
83
+ info[f] = i
84
+ rescue
85
+ Log.exception $!
86
+ end
87
+ end
88
+ info
89
+ end
90
+
91
+ # PERSISTS
92
+
22
93
  def self.persists(dirs = PERSIST_DIRS)
23
94
  dirs.collect do |dir|
24
- dir.glob("**/*.persist").reject{|f| f =~ /\.lock$/ }
25
- end.flatten
95
+ next unless Open.exists? dir
96
+ `find "#{ dir }" -name "*.persist"`.split "\n"
97
+ end.compact.flatten
26
98
  end
27
99
 
28
- JOB_DIRS = Rbbt.var.jobs.find_all
29
- def self.jobs(dirs = JOB_DIRS)
100
+ def self.persist_info(dirs = PERSIST_DIRS)
101
+ info = {}
102
+ persists(dirs).each do |f|
103
+ begin
104
+ i = file_time(f)
105
+ info[f] = i
106
+ rescue
107
+ Log.exception $!
108
+ end
109
+ end
110
+ info
111
+ end
112
+
113
+ # PERSISTS
114
+
115
+ def self.job_info(workflows = nil, tasks = nil, dirs = JOB_DIRS)
116
+ require 'rbbt/workflow/step'
117
+
118
+ workflows = [workflows] if workflows and not Array === workflows
119
+ workflows = workflows.collect{|w| w.to_s} if workflows
120
+
121
+ tasks = [tasks] if tasks and not Array === tasks
122
+ tasks = tasks.collect{|w| w.to_s} if tasks
123
+
124
+ jobs = {}
125
+ dirs.collect do |dir|
126
+ next unless Open.exists? dir
127
+
128
+ dir.glob("*").collect do |workflowdir|
129
+ workflow = File.basename(workflowdir)
130
+ next if workflows and not workflows.include? workflow
131
+
132
+ workflowdir.glob("*").collect do |taskdir|
133
+ task = File.basename(taskdir)
134
+ next if tasks and not tasks.include? task
135
+
136
+ files = `find "#{ taskdir }/" -not -type d -not -path "*/*.files/*"`.split("\n").sort
137
+ _files = Set.new files
138
+ TSV.traverse files, :type => :array, :into => jobs do |file|
139
+ if m = file.match(/(.*).info$/)
140
+ file = m[1]
141
+ end
142
+
143
+ name = file[taskdir.length+1..-1]
144
+ info_file = file + '.info'
145
+
146
+ info = {}
147
+
148
+ info[:workflow] = workflow
149
+ info[:task] = task
150
+ info[:name] = name
151
+
152
+ if _files.include? file
153
+ info = info.merge(file_time(file))
154
+ info[:done] = true
155
+ info[:info_file] = File.exists?(info_file) ? info_file : nil
156
+ else
157
+ info = info.merge({:info_file => info_file, :done => false})
158
+ end
159
+
160
+ [file, info]
161
+ end
162
+
163
+ end.compact.flatten
164
+ end.compact.flatten
165
+ end.compact.flatten
166
+ jobs
167
+ end
168
+
169
+ # REST
170
+
171
+ def self.__jobs(dirs = JOB_DIRS)
30
172
  job_files = {}
31
173
  dirs.each do |dir|
32
174
  workflow_dirs = dir.glob("*").each do |wdir|
@@ -0,0 +1,109 @@
1
+ require 'rbbt/tsv'
2
+ module Persist
3
+ module TSVAdapter
4
+ attr_accessor :persistence_path, :closed, :writable, :mutex
5
+
6
+ MAX_CHAR = 255.chr
7
+
8
+ def mutex
9
+ @mutex ||= Mutex.new
10
+ end
11
+
12
+ def prefix(key)
13
+ range(key, 1, key + MAX_CHAR, 1)
14
+ end
15
+
16
+ def get_prefix(key)
17
+ keys = prefix(key)
18
+ select(:key => keys)
19
+ end
20
+
21
+ def closed?
22
+ @closed
23
+ end
24
+
25
+ def close
26
+ @closed = true
27
+ super
28
+ self
29
+ end
30
+
31
+ def write?
32
+ @writable
33
+ end
34
+
35
+ def read?
36
+ ! write?
37
+ end
38
+
39
+ def collect
40
+ res = []
41
+ each do |key, value|
42
+ res << if block_given?
43
+ yield key, value
44
+ else
45
+ [key, value]
46
+ end
47
+ end
48
+ res
49
+ end
50
+
51
+ def delete(key)
52
+ out(key)
53
+ end
54
+
55
+ def write_and_read
56
+ lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
57
+ Misc.lock(lock_filename) do
58
+ mutex.synchronize do
59
+ write if closed? or not write?
60
+ res = begin
61
+ yield
62
+ ensure
63
+ read
64
+ end
65
+ res
66
+ end
67
+ end
68
+ end
69
+
70
+ def write_and_close
71
+ lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
72
+ Misc.lock(lock_filename) do
73
+ mutex.synchronize do
74
+ write if closed? or not write?
75
+ res = begin
76
+ yield
77
+ ensure
78
+ close
79
+ end
80
+ res
81
+ end
82
+ end
83
+ end
84
+
85
+ def read_and_close
86
+ mutex.synchronize do
87
+ read if closed? or not read?
88
+ res = begin
89
+ yield
90
+ ensure
91
+ close
92
+ end
93
+ res
94
+ end
95
+ end
96
+
97
+
98
+ def merge!(hash)
99
+ hash.each do |key,values|
100
+ self[key] = values
101
+ end
102
+ end
103
+
104
+
105
+ def range(*args)
106
+ super(*args) #- TSV::ENTRY_KEYS.to_a
107
+ end
108
+ end
109
+ end
@@ -3,7 +3,8 @@ require 'kyotocabinet'
3
3
  module Persist
4
4
 
5
5
  module KCAdapter
6
- attr_accessor :persistence_path, :kyotocabinet_class, :closed, :writable
6
+ include Persist::TSVAdapter
7
+ attr_accessor :kyotocabinet_class
7
8
 
8
9
  def self.open(path, write, kyotocabinet_class = "kch")
9
10
  real_path = path + ".#{kyotocabinet_class}"
@@ -24,33 +25,10 @@ module Persist
24
25
  database
25
26
  end
26
27
 
27
- def keys
28
- keys = []
29
- each_key{|k| keys.concat k}
30
- keys
31
- end
32
-
33
- def prefix(key)
34
- range(key, 1, key + 255.chr, 1)
35
- end
36
-
37
- def get_prefix(key)
38
- keys = prefix(key)
39
- select(:key => keys)
40
- end
41
-
42
- def include?(key)
43
- value = get(key)
44
- ! value.nil?
45
- end
46
-
47
- def closed?
48
- @closed
49
- end
50
-
51
28
  def close
52
29
  @closed = true
53
30
  super
31
+ self
54
32
  end
55
33
 
56
34
  def read(force = false)
@@ -96,58 +74,6 @@ module Persist
96
74
  def delete(key)
97
75
  out(key)
98
76
  end
99
-
100
- def write_and_read
101
- lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
102
- Misc.lock(lock_filename) do
103
- write if @closed or not write?
104
- res = begin
105
- yield
106
- ensure
107
- read
108
- end
109
- res
110
- end
111
- end
112
-
113
- def write_and_close
114
- lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
115
- Misc.lock(lock_filename) do
116
- write if @closed or not write?
117
- res = begin
118
- yield
119
- ensure
120
- close
121
- end
122
- res
123
- end
124
- end
125
-
126
- def read_and_close
127
- read if @closed or write?
128
- res = begin
129
- yield
130
- ensure
131
- close
132
- end
133
- res
134
- end
135
-
136
- def merge!(hash)
137
- hash.each do |key,values|
138
- self[key] = values
139
- end
140
- end
141
-
142
- #def []=(key,value)
143
- # super(key,value)
144
- # self.synchronize
145
- #end
146
-
147
-
148
- def range(*args)
149
- super(*args) - TSV::ENTRY_KEYS.to_a
150
- end
151
77
  end
152
78
 
153
79
 
@@ -3,8 +3,7 @@ require 'lmdb'
3
3
  module Persist
4
4
 
5
5
  module LMDBAdapter
6
- attr_accessor :persistence_path, :closed
7
-
6
+ include Persist::TSVAdapter
8
7
  def self.open(path, write)
9
8
 
10
9
  database = CONNECTIONS[path] ||= begin
@@ -21,40 +20,6 @@ module Persist
21
20
  database
22
21
  end
23
22
 
24
- def keys
25
- keys = []
26
- cursor do |cursor|
27
- while p = cursor.next
28
- keys << p.first
29
- end
30
- end
31
- keys
32
- end
33
-
34
- def include?(key)
35
- self.send(:[], key, true)
36
- end
37
-
38
- def closed?
39
- false
40
- end
41
-
42
- def close
43
- self
44
- end
45
-
46
- def read(force = false)
47
- self
48
- end
49
-
50
- def write(force = true)
51
- self
52
- end
53
-
54
- def write?
55
- @writable
56
- end
57
-
58
23
  def each
59
24
  cursor do |cursor|
60
25
  while pair = cursor.next
@@ -77,60 +42,8 @@ module Persist
77
42
  end
78
43
  res
79
44
  end
80
-
81
- def delete(key)
82
- out(key)
83
- end
84
-
85
- def write_and_read
86
- lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
87
- Misc.lock(lock_filename) do
88
- write if @closed or not write?
89
- res = begin
90
- yield
91
- ensure
92
- read
93
- end
94
- res
95
- end
96
- end
97
-
98
- def write_and_close
99
- lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
100
- Misc.lock(lock_filename) do
101
- write if @closed or not write?
102
- res = begin
103
- yield
104
- ensure
105
- close
106
- end
107
- res
108
- end
109
- end
110
-
111
- def read_and_close
112
- read if @closed or write?
113
- res = begin
114
- yield
115
- ensure
116
- close
117
- end
118
- res
119
- end
120
-
121
- def merge!(hash)
122
- hash.each do |key,values|
123
- self[key] = values
124
- end
125
- end
126
-
127
-
128
- def range(*args)
129
- super(*args) - TSV::ENTRY_KEYS.to_a
130
- end
131
45
  end
132
46
 
133
-
134
47
  def self.open_lmdb(path, write, serializer = nil)
135
48
  write = true unless File.exists? path
136
49