nera 0.0.1
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.
- 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
|