nera 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +37 -0
- data/README.rdoc +47 -0
- data/Rakefile +27 -0
- data/bin/nera +29 -0
- data/bin/nera_addsim +30 -0
- data/lib/nera/nera_cui.rb +417 -0
- data/lib/nera/nera_database.rb +281 -0
- data/lib/nera/nera_db_folders.rb +226 -0
- data/lib/nera/nera_dialog.rb +205 -0
- data/lib/nera/nera_job_layer_controller.rb +237 -0
- data/lib/nera/nera_job_records.rb +111 -0
- data/lib/nera/nera_job_script.rb +202 -0
- data/lib/nera/nera_parameter_layer_controller.rb +157 -0
- data/lib/nera/nera_parameter_records.rb +186 -0
- data/lib/nera/nera_run_layer_controller.rb +192 -0
- data/lib/nera/nera_run_records.rb +184 -0
- data/lib/nera/nera_simulator.rb +26 -0
- data/lib/nera/nera_simulator_layer_controller.rb +66 -0
- data/lib/nera/nera_simulator_records.rb +84 -0
- data/lib/nera.rb +25 -0
- data/lib/nera_addsim/make_simulator.rb +307 -0
- data/scripts/make_manifest.rb +21 -0
- data/test/runner.rb +3 -0
- data/test/test_helper.rb +52 -0
- data/test/test_nera_database.rb +221 -0
- data/test/test_nera_db_folders.rb +209 -0
- data/test/test_nera_dialog.rb +134 -0
- data/test/test_nera_job_layer_controller.rb +132 -0
- data/test/test_nera_job_records.rb +260 -0
- data/test/test_nera_parameter_layer_controller.rb +188 -0
- data/test/test_nera_parameter_records.rb +285 -0
- data/test/test_nera_run_layer_controller.rb +171 -0
- data/test/test_nera_run_records.rb +290 -0
- data/test/test_nera_simulator.rb +26 -0
- data/test/test_nera_simulator_layer_controller.rb +54 -0
- data/test/test_nera_simulator_records.rb +140 -0
- metadata +125 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'nera_database'
|
2
|
+
require 'nera_simulator'
|
3
|
+
|
4
|
+
module NERA
|
5
|
+
|
6
|
+
# The parameter tables are accessed from this class
|
7
|
+
class ParameterRecords
|
8
|
+
|
9
|
+
# keys of the parameter table
|
10
|
+
ATTRIBUTES_PART = [ [:id, Integer],
|
11
|
+
[:created_at, DateTime],
|
12
|
+
[:updated_at, DateTime],
|
13
|
+
[:in_trashbox?, Symbol] ] # :active or :trashbox
|
14
|
+
|
15
|
+
# NERA::Database object
|
16
|
+
@db
|
17
|
+
|
18
|
+
# attributes (keys)
|
19
|
+
@keys
|
20
|
+
attr_reader :keys
|
21
|
+
|
22
|
+
# simulator_specific keys
|
23
|
+
@sim_class
|
24
|
+
|
25
|
+
# argument is the path to database file
|
26
|
+
def initialize( db_file, sim_class)
|
27
|
+
unless sim_class.superclass == NERA::Simulator
|
28
|
+
raise ArgumentError, "Given simulator class is not a subclass of NERA::Simulator : #{sim_class}"
|
29
|
+
end
|
30
|
+
@sim_class = sim_class
|
31
|
+
@keys = ATTRIBUTES_PART.map do |k|
|
32
|
+
k[0]
|
33
|
+
end
|
34
|
+
sim_keys = @sim_class::Parameters.map do |x|
|
35
|
+
x[0]
|
36
|
+
end
|
37
|
+
found = @keys.find do |a|
|
38
|
+
sim_keys.include?(a)
|
39
|
+
end
|
40
|
+
if found
|
41
|
+
raise ArgumentError, "Invalid class. This class has a parameter : #{found}"
|
42
|
+
end
|
43
|
+
@keys += sim_keys
|
44
|
+
@db = NERA::Database.new( db_file)
|
45
|
+
end
|
46
|
+
|
47
|
+
# if file already exists, return false
|
48
|
+
def self.create_table( db_file, sim_class)
|
49
|
+
unless sim_class.superclass == NERA::Simulator
|
50
|
+
raise ArgumentError, "Given simulator class is not a subclass of NERA::Simulator : #{sim_class}"
|
51
|
+
end
|
52
|
+
ks = ATTRIBUTES_PART.map do |k|
|
53
|
+
k[0]
|
54
|
+
end
|
55
|
+
params = sim_class::Parameters.map do |x|
|
56
|
+
x[0]
|
57
|
+
end
|
58
|
+
found = ks.find do |a|
|
59
|
+
params.include?(a)
|
60
|
+
end
|
61
|
+
if found
|
62
|
+
raise ArgumentError, "Invalid class. This class has a parameter : #{found}"
|
63
|
+
end
|
64
|
+
NERA::Database.create_table( db_file)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
def add( param_hash)
|
69
|
+
# check the argument
|
70
|
+
unless param_hash.is_a?(Hash)
|
71
|
+
raise ArgumentError, "Argument must be a Hash."
|
72
|
+
end
|
73
|
+
|
74
|
+
# check the argument
|
75
|
+
sim_keys = @sim_class::Parameters.map do |x|
|
76
|
+
x[0]
|
77
|
+
end
|
78
|
+
param_hash.each_pair do |param,value|
|
79
|
+
unless sim_keys.include?(param)
|
80
|
+
raise ArgumentError, "The given parameter set has unknown key."
|
81
|
+
end
|
82
|
+
a = @sim_class::Parameters.find do |p|
|
83
|
+
p[0] == param
|
84
|
+
end
|
85
|
+
unless value.is_a?( a[1] )
|
86
|
+
raise ArgumentError, "The given parameter set has invalid type."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# check duplication
|
91
|
+
found = @db.find_all do |rec|
|
92
|
+
f = true
|
93
|
+
@sim_class::Parameters.each do |p|
|
94
|
+
# set default values
|
95
|
+
rec[ p[0] ] = p[2] if rec[ p[0] ] == nil
|
96
|
+
param_hash[ p[0] ] = p[2] if param_hash[ p[0]] == nil
|
97
|
+
unless rec[p[0]] == param_hash[p[0]]
|
98
|
+
f = false
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
f
|
103
|
+
end
|
104
|
+
if found # the given parameter set already exists.
|
105
|
+
return nil
|
106
|
+
end
|
107
|
+
|
108
|
+
# add a parameter
|
109
|
+
d = DateTime.now
|
110
|
+
h = {:created_at => d, :updated_at => d, :in_trashbox? => :active}
|
111
|
+
ps = param_hash.dup
|
112
|
+
@sim_class::Parameters.each do |p|
|
113
|
+
ps[ p[0]] = p[3] if ps[p[0]] == nil
|
114
|
+
end
|
115
|
+
h.merge!( ps)
|
116
|
+
@db.add(h)
|
117
|
+
end
|
118
|
+
|
119
|
+
def list_all
|
120
|
+
list = @db.find_all do |r|
|
121
|
+
true
|
122
|
+
end
|
123
|
+
return list.to_a
|
124
|
+
end
|
125
|
+
|
126
|
+
def list_active
|
127
|
+
list = @db.find_all do |r|
|
128
|
+
r[:in_trashbox?] == :active
|
129
|
+
end
|
130
|
+
return list.to_a
|
131
|
+
end
|
132
|
+
|
133
|
+
def list_trashbox
|
134
|
+
list = @db.find_all do |r|
|
135
|
+
r[:in_trashbox?] == :trashbox
|
136
|
+
end
|
137
|
+
return list.to_a
|
138
|
+
end
|
139
|
+
|
140
|
+
def find_by_id( id)
|
141
|
+
@db.find_by_id( id)
|
142
|
+
end
|
143
|
+
|
144
|
+
def update_to_state_active( id)
|
145
|
+
raise ArgumentError unless id.is_a?(Integer)
|
146
|
+
found = @db.find_by_id( id)
|
147
|
+
return nil unless found
|
148
|
+
return nil if found[:in_trashbox?] == :active
|
149
|
+
|
150
|
+
found[:in_trashbox?] = :active
|
151
|
+
@db.update( found)
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_to_state_trashbox( id)
|
155
|
+
raise ArgumentError unless id.is_a?(Integer)
|
156
|
+
found = @db.find_by_id( id)
|
157
|
+
return nil unless found
|
158
|
+
return nil if found[:in_trashbox?] == :trashbox
|
159
|
+
|
160
|
+
found[:in_trashbox?] = :trashbox
|
161
|
+
@db.update( found)
|
162
|
+
end
|
163
|
+
|
164
|
+
def touch( id)
|
165
|
+
raise ArgumentError unless id.is_a?(Integer)
|
166
|
+
found = @db.find_by_id( id)
|
167
|
+
return nil unless found
|
168
|
+
found[:updated_at] = DateTime.now
|
169
|
+
@db.update( found)
|
170
|
+
end
|
171
|
+
|
172
|
+
def destroy( id)
|
173
|
+
raise ArgumentError unless id.is_a?(Integer)
|
174
|
+
found = @db.find_by_id( id)
|
175
|
+
return nil if found == nil or found[:in_trashbox?] == :active
|
176
|
+
@db.destroy(id)
|
177
|
+
end
|
178
|
+
|
179
|
+
def transaction
|
180
|
+
@db.transaction{
|
181
|
+
yield
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'nera_db_folders'
|
3
|
+
require 'nera_simulator_records'
|
4
|
+
require 'nera_parameter_records'
|
5
|
+
require 'nera_run_records'
|
6
|
+
require 'nera_job_records'
|
7
|
+
require 'nera_job_script'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
module NERA
|
11
|
+
|
12
|
+
class RunLayerController
|
13
|
+
|
14
|
+
# instance of NERA::DbFolders
|
15
|
+
@db_folders
|
16
|
+
# instance of NERA::Simulator class
|
17
|
+
@sim_instance
|
18
|
+
# id of the parameter set
|
19
|
+
@param_id
|
20
|
+
# instance of NERA::RunRecords
|
21
|
+
@run_records
|
22
|
+
|
23
|
+
def initialize( path_db_folder, sim_class, param_id)
|
24
|
+
raise ArgumentError unless path_db_folder.is_a?(String)
|
25
|
+
unless sim_class.is_a?(Class) and sim_class.superclass == NERA::Simulator and param_id.is_a?(Integer)
|
26
|
+
raise ArgumentError, "#{sim_class}, #{param_id} are not appropriate instances"
|
27
|
+
end
|
28
|
+
|
29
|
+
@db_folders = NERA::DbFolders.new( path_db_folder)
|
30
|
+
@sim_instance = sim_class.new
|
31
|
+
@param_id = param_id
|
32
|
+
param_records = NERA::ParameterRecords.new( @db_folders.path_to_parameters_table( sim_class), sim_class)
|
33
|
+
found = param_records.find_by_id( @param_id)
|
34
|
+
@sim_instance.class::Parameters.each do |pa|
|
35
|
+
key = pa[0]
|
36
|
+
if found[key]
|
37
|
+
@sim_instance.param[key] = found[key]
|
38
|
+
else
|
39
|
+
@sim_instance.param[key] = pa[2]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@run_records = NERA::RunRecords.new( @db_folders.path_to_runs_table( sim_class, @param_id) )
|
44
|
+
end
|
45
|
+
|
46
|
+
def path_to_run_layer
|
47
|
+
return @db_folders.path_to_run_layer( @sim_instance.class, @param_id)
|
48
|
+
end
|
49
|
+
|
50
|
+
def all_runs_list_in_csv
|
51
|
+
list = @run_records.list_all
|
52
|
+
header = @run_records.keys.dup
|
53
|
+
csv_list = []
|
54
|
+
list.each do |r_hash|
|
55
|
+
strings = []
|
56
|
+
header.each do |key|
|
57
|
+
if r_hash[key].is_a?(DateTime)
|
58
|
+
strings << r_hash[key].to_s.split('T')[0]
|
59
|
+
else
|
60
|
+
strings << r_hash[key].to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
csv_list << strings.join(", ")
|
64
|
+
end
|
65
|
+
return header.join(", "), csv_list
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_jobs( num_jobs, num_runs_per_job = 1)
|
69
|
+
unless num_jobs.is_a?(Integer) and num_jobs >= 0
|
70
|
+
raise ArgumentError, "num_jobs must be equal to or larger than zero."
|
71
|
+
end
|
72
|
+
|
73
|
+
job_ids = []
|
74
|
+
job_recs = NERA::JobRecords.new( @db_folders.path_to_jobs_table)
|
75
|
+
js = NERA::JobScript.new( @db_folders)
|
76
|
+
job_recs.transaction {
|
77
|
+
@run_records.transaction {
|
78
|
+
num_jobs.times do |j_idx|
|
79
|
+
run_stat = @run_records.add( num_runs_per_job)
|
80
|
+
rid = run_stat[0][:id]
|
81
|
+
jid = job_recs.add( @sim_instance.class, @param_id, rid, num_runs_per_job)
|
82
|
+
@run_records.set_job_id( rid, num_runs_per_job, jid)
|
83
|
+
sim_records = NERA::SimulatorRecords.new( @db_folders.path_to_simulators_table)
|
84
|
+
found = sim_records.list.find do |rec| rec[:name] == @sim_instance.class.to_s end
|
85
|
+
path_script = js.create_script( jid, found[:id], @param_id, @sim_instance, run_stat)
|
86
|
+
job_ids << jid
|
87
|
+
end
|
88
|
+
}
|
89
|
+
}
|
90
|
+
dump_in_yaml( job_recs)
|
91
|
+
return job_ids
|
92
|
+
end
|
93
|
+
|
94
|
+
def not_finished_jobs_list_in_csv
|
95
|
+
list = @run_records.list_all_not_finished
|
96
|
+
header = "job_id, created_at, run_id, num_runs, omp_threads, mpi_processes"
|
97
|
+
|
98
|
+
jobids = list.map do |rec|
|
99
|
+
rec[:job_id]
|
100
|
+
end
|
101
|
+
jobids = jobids.sort.uniq
|
102
|
+
|
103
|
+
csv_list = []
|
104
|
+
jobids.each do |jid|
|
105
|
+
strings = [ jid]
|
106
|
+
found = list.find_all do |r| r[:job_id] == jid end
|
107
|
+
found_first = found.first
|
108
|
+
strings << found_first[:created_at].to_s.split('T')[0]
|
109
|
+
strings << found_first[:id]
|
110
|
+
strings << found.size
|
111
|
+
strings << found_first[:omp_threads]
|
112
|
+
strings << found_first[:mpi_processes]
|
113
|
+
csv_list << strings.join(", ")
|
114
|
+
end
|
115
|
+
return header, csv_list
|
116
|
+
end
|
117
|
+
|
118
|
+
def cancel_jobs( job_ids)
|
119
|
+
unless job_ids.is_a?(Array)
|
120
|
+
raise ArgumentError, "job_ids must be an Array."
|
121
|
+
end
|
122
|
+
job_ids.each do |x|
|
123
|
+
raise ArgumentError, "each element of job_ids must be an Integer" unless x.is_a?(Integer)
|
124
|
+
end
|
125
|
+
|
126
|
+
job_recs = NERA::JobRecords.new( @db_folders.path_to_jobs_table)
|
127
|
+
job_recs.transaction {
|
128
|
+
@run_records.transaction {
|
129
|
+
job_ids.each do |jid|
|
130
|
+
d = job_recs.destroy(jid)
|
131
|
+
next unless d
|
132
|
+
a = @run_records.destroy_job_id( jid)
|
133
|
+
raise "must not happen" unless a
|
134
|
+
FileUtils.rm( @db_folders.path_to_job_script(jid) )
|
135
|
+
end
|
136
|
+
}
|
137
|
+
}
|
138
|
+
dump_in_yaml( job_recs)
|
139
|
+
return true
|
140
|
+
end
|
141
|
+
|
142
|
+
def analysis_methods
|
143
|
+
found = @sim_instance.public_methods.find_all do |meth|
|
144
|
+
meth =~ /^analyze_/
|
145
|
+
end
|
146
|
+
return found
|
147
|
+
end
|
148
|
+
|
149
|
+
def analyze( method_str)
|
150
|
+
unless method_str.is_a?(String) or method_str.is_a?(Symbol)
|
151
|
+
raise ArgumentError, "method_str must be a String or Symbol"
|
152
|
+
end
|
153
|
+
|
154
|
+
return nil unless method_str.to_s =~ /^analyze_/
|
155
|
+
|
156
|
+
found = @sim_instance.public_methods.find do |m|
|
157
|
+
m == method_str.to_s
|
158
|
+
end
|
159
|
+
return nil unless found
|
160
|
+
|
161
|
+
FileUtils.cd( @db_folders.path_to_run_layer(@sim_instance.class, @param_id) ) {
|
162
|
+
@sim_instance.__send__( method_str)
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def analyze_all
|
167
|
+
found = @sim_instance.public_methods.find_all do |m|
|
168
|
+
m =~ /^analyze_/
|
169
|
+
end
|
170
|
+
return nil unless found
|
171
|
+
|
172
|
+
FileUtils.cd( @db_folders.path_to_run_layer(@sim_instance.class, @param_id) ) {
|
173
|
+
found.each do |meth|
|
174
|
+
@sim_instance.__send__( meth)
|
175
|
+
end
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
def dump_in_yaml( job_recs)
|
181
|
+
File.open( @db_folders.path_to_runs_yaml( @sim_instance.class, @param_id), 'w') do |io|
|
182
|
+
YAML.dump( @run_records.list_all, io)
|
183
|
+
io.flush
|
184
|
+
end
|
185
|
+
File.open( @db_folders.path_to_jobs_yaml, 'w') do |io|
|
186
|
+
YAML.dump( job_recs.list_all, io)
|
187
|
+
io.flush
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'nera_database'
|
3
|
+
|
4
|
+
module NERA
|
5
|
+
class RunRecords
|
6
|
+
|
7
|
+
# keys of run records
|
8
|
+
ATTRIBUTES = [ [:id, Integer], [:state, Symbol], [:created_at, DateTime],
|
9
|
+
[:job_id, Integer], [:seed, Integer],
|
10
|
+
[:start_at, DateTime], [:finish_at, DateTime],
|
11
|
+
[:included_at, DateTime], [:real_time, Float],
|
12
|
+
[:user_time, Float], [:host_name, String],
|
13
|
+
[:omp_threads, Integer], [:mpi_processes, Integer]
|
14
|
+
]
|
15
|
+
|
16
|
+
# Maximum of the seed
|
17
|
+
SEED_MAX = 2**31
|
18
|
+
|
19
|
+
# NERA::Database object (table object)
|
20
|
+
@db
|
21
|
+
|
22
|
+
# record
|
23
|
+
@keys
|
24
|
+
attr_accessor :keys
|
25
|
+
|
26
|
+
# run record
|
27
|
+
def initialize( table_file)
|
28
|
+
@keys = ATTRIBUTES.map do |k| k[0] end
|
29
|
+
@db = NERA::Database.new( table_file)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.create_table(table_file)
|
33
|
+
NERA::Database.create_table( table_file)
|
34
|
+
end
|
35
|
+
|
36
|
+
public
|
37
|
+
def add( num_runs, omp_threads = 1, mpi_procs = 1)
|
38
|
+
# check arguments
|
39
|
+
unless num_runs.is_a?(Integer) and num_runs > 0
|
40
|
+
raise ArgumentError, "Number of runs must be a postive integer."
|
41
|
+
end
|
42
|
+
unless (omp_threads.is_a?(Integer) and omp_threads > 0) or omp_threads == nil
|
43
|
+
raise ArgumentError, "omp_threads must be a postive integer or nil"
|
44
|
+
end
|
45
|
+
unless (mpi_procs.is_a?(Integer) and mpi_procs > 0) or mpi_procs == nil
|
46
|
+
raise ArgumentError, "mpi_procs must be a postive integer or nil"
|
47
|
+
end
|
48
|
+
|
49
|
+
stats = []
|
50
|
+
@db.transaction {
|
51
|
+
seeds = find_unique_seed( num_runs)
|
52
|
+
d = DateTime.now
|
53
|
+
num_runs.times do |i|
|
54
|
+
h = {:state => :not_finished, :created_at => d, :job_id => nil, :seed => seeds[i], :omp_threads => omp_threads, :mpi_processes => mpi_procs}
|
55
|
+
new_id = @db.add( h)
|
56
|
+
found = @db.find_by_id( new_id)
|
57
|
+
stat = Hash.new
|
58
|
+
stat[:id] = found[:id]
|
59
|
+
stat[:seed] = found[:seed]
|
60
|
+
stat[:omp_threads] = found[:omp_threads]
|
61
|
+
stat[:mpi_processes] = found[:mpi_processes]
|
62
|
+
stats << stat
|
63
|
+
end
|
64
|
+
}
|
65
|
+
return stats
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def find_unique_seed( num_runs)
|
70
|
+
seeds = []
|
71
|
+
until seeds.size == num_runs
|
72
|
+
sed = rand( SEED_MAX)
|
73
|
+
found = @db.find_all do |rec|
|
74
|
+
rec[:seed] == sed
|
75
|
+
end
|
76
|
+
seeds << sed unless found
|
77
|
+
end
|
78
|
+
return seeds
|
79
|
+
end
|
80
|
+
|
81
|
+
public
|
82
|
+
def set_job_id( id, num_runs, j_id)
|
83
|
+
# check arguments
|
84
|
+
unless id.is_a?(Integer) and num_runs.is_a?(Integer) and j_id.is_a?(Integer)
|
85
|
+
raise ArgumentError, "Arguments must be Integers."
|
86
|
+
end
|
87
|
+
|
88
|
+
@db.transaction {
|
89
|
+
for i in id...(id+num_runs) do
|
90
|
+
r = @db.find_by_id(i)
|
91
|
+
raise RuntimeError, "The record #{id} is not found." unless r
|
92
|
+
raise RuntimeError, "The record #{id} already has job_id." if r[:job_id]
|
93
|
+
r[:job_id] = j_id
|
94
|
+
@db.update(r)
|
95
|
+
end
|
96
|
+
flag = true
|
97
|
+
}
|
98
|
+
return j_id
|
99
|
+
end
|
100
|
+
|
101
|
+
def list_all
|
102
|
+
matched = @db.find_all do |rec|
|
103
|
+
true
|
104
|
+
end
|
105
|
+
return matched.to_a
|
106
|
+
end
|
107
|
+
|
108
|
+
def list_all_finished
|
109
|
+
matched = @db.find_all do |rec|
|
110
|
+
rec[:state] == :finished
|
111
|
+
end
|
112
|
+
return matched.to_a
|
113
|
+
end
|
114
|
+
|
115
|
+
def list_all_not_finished
|
116
|
+
matched = @db.find_all do |rec|
|
117
|
+
rec[:state] == :not_finished
|
118
|
+
end
|
119
|
+
return matched.to_a
|
120
|
+
end
|
121
|
+
|
122
|
+
def update_state_to_finished( id, start_at, finish_at, included_at, real_time, user_time, host_name)
|
123
|
+
unless id.is_a?(Integer) and start_at.is_a?(DateTime) and finish_at.is_a?(DateTime)
|
124
|
+
p id, start_at, finish_at
|
125
|
+
raise ArgumentError
|
126
|
+
end
|
127
|
+
unless included_at.is_a?(DateTime) and real_time.is_a?(Float) and user_time.is_a?(Float) and host_name.is_a?(String)
|
128
|
+
p included_at, real_time, user_time, host_name
|
129
|
+
raise ArgumentError
|
130
|
+
end
|
131
|
+
|
132
|
+
flag = nil
|
133
|
+
@db.transaction {
|
134
|
+
found = @db.find_by_id( id)
|
135
|
+
return nil unless found
|
136
|
+
return nil if found[:state] == :finished
|
137
|
+
found[:start_at] = start_at
|
138
|
+
found[:finish_at] = finish_at
|
139
|
+
found[:included_at] = included_at
|
140
|
+
found[:real_time] = real_time
|
141
|
+
found[:user_time] = user_time
|
142
|
+
found[:host_name] = host_name
|
143
|
+
found[:state] = :finished
|
144
|
+
flag = @db.update( found)
|
145
|
+
}
|
146
|
+
return flag
|
147
|
+
end
|
148
|
+
|
149
|
+
def destroy( id)
|
150
|
+
raise ArgumentError unless id.is_a?(Integer)
|
151
|
+
|
152
|
+
flag = nil
|
153
|
+
@db.transaction {
|
154
|
+
found = @db.find_by_id(id)
|
155
|
+
return nil unless found
|
156
|
+
return nil if found[:state] == :finished
|
157
|
+
flag = @db.destroy(id)
|
158
|
+
}
|
159
|
+
return flag
|
160
|
+
end
|
161
|
+
|
162
|
+
def destroy_job_id( job_id)
|
163
|
+
raise ArgumentError unless job_id.is_a?(Integer)
|
164
|
+
|
165
|
+
@db.transaction {
|
166
|
+
found = list_all_not_finished.find_all do |rec|
|
167
|
+
rec[:job_id] == job_id
|
168
|
+
end
|
169
|
+
return nil if found.size == 0
|
170
|
+
found.each do |rec|
|
171
|
+
f = @db.destroy( rec[:id])
|
172
|
+
raise "must not happen" unless f
|
173
|
+
end
|
174
|
+
}
|
175
|
+
return true
|
176
|
+
end
|
177
|
+
|
178
|
+
def transaction
|
179
|
+
@db.transaction{
|
180
|
+
yield
|
181
|
+
}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module NERA
|
2
|
+
|
3
|
+
class Simulator
|
4
|
+
|
5
|
+
# instance variables
|
6
|
+
@param
|
7
|
+
attr_accessor :param
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@param = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# class methods, variables
|
14
|
+
@@inherited = []
|
15
|
+
|
16
|
+
def self.inherited(subclass)
|
17
|
+
@@inherited << subclass
|
18
|
+
end
|
19
|
+
|
20
|
+
public
|
21
|
+
def self.inherited_simulators
|
22
|
+
return @@inherited
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'nera_db_folders'
|
2
|
+
require 'nera_simulator_records'
|
3
|
+
require 'nera_parameter_records'
|
4
|
+
|
5
|
+
module NERA
|
6
|
+
|
7
|
+
class SimulatorLayerController
|
8
|
+
|
9
|
+
# instance of NERA::DbFolders
|
10
|
+
@db_folders
|
11
|
+
# instance of NERA::SimulatorRecords
|
12
|
+
@sim_records
|
13
|
+
|
14
|
+
def initialize( path_db_folds)
|
15
|
+
raise ArgumentError unless path_db_folds.is_a?(String)
|
16
|
+
|
17
|
+
@db_folders = NERA::DbFolders.new( path_db_folds)
|
18
|
+
table_path = @db_folders.path_to_simulators_table
|
19
|
+
@sim_records = NERA::SimulatorRecords.new(table_path)
|
20
|
+
|
21
|
+
NERA::Simulator.inherited_simulators.each do |sim|
|
22
|
+
next if list.find do |rec| rec[:name] == sim.to_s end
|
23
|
+
found = sim::Parameters.find do |p|
|
24
|
+
p[0] == :in_trashbox? or p[0] == :created_at or p[0] == :updated_at
|
25
|
+
end
|
26
|
+
next if found
|
27
|
+
register_a_simulator( sim)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def list
|
32
|
+
@sim_records.list
|
33
|
+
end
|
34
|
+
|
35
|
+
def path_to_sim_layer
|
36
|
+
@db_folders.path_to_simulator_layer
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def register_a_simulator( sim_klass)
|
41
|
+
a = nil
|
42
|
+
@sim_records.transaction {
|
43
|
+
a = @sim_records.add( sim_klass)
|
44
|
+
return nil unless a
|
45
|
+
b = @db_folders.create_new_simulator_folder( sim_klass)
|
46
|
+
raise "The folder #{sim_klass.to_s}/ already exists." unless b
|
47
|
+
path = @db_folders.path_to_parameters_table( sim_klass)
|
48
|
+
c = NERA::ParameterRecords.create_table( path, sim_klass)
|
49
|
+
raise "The file #{path} already exists." unless c
|
50
|
+
}
|
51
|
+
dump_in_yaml
|
52
|
+
return a
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def dump_in_yaml
|
57
|
+
ymlpath = @db_folders.path_to_simulators_yaml
|
58
|
+
File.open( ymlpath, 'w') do |io|
|
59
|
+
YAML::dump( @sim_records.list, io)
|
60
|
+
io.flush
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|