neptune 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -170,6 +170,18 @@ cluttering up <a href="Object.html">Object</a> or Kernel’s namespace.</p>
170
170
  <dd class="description">
171
171
 
172
172
 
173
+ <dt id="GET_CPU_INFO">GET_CPU_INFO
174
+
175
+ <dd class="description"><p>The command that we can run to get information about the number and speed
176
+ of CPUs on this machine.</p>
177
+
178
+
179
+ <dt id="NEPTUNE_DATA_DIR">NEPTUNE_DATA_DIR
180
+
181
+ <dd class="description"><p>The location on this machine where we can read and write profiling
182
+ information about jobs.</p>
183
+
184
+
173
185
  <dt id="OPTIMIZE_FOR_CHOICES">OPTIMIZE_FOR_CHOICES
174
186
 
175
187
  <dd class="description">
@@ -208,7 +220,7 @@ cluttering up <a href="Object.html">Object</a> or Kernel’s namespace.</p>
208
220
 
209
221
 
210
222
  <div class="method-source-code" id="average-source">
211
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 268</span>
223
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 316</span>
212
224
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">average</span>(<span class="ruby-identifier">vals</span>)
213
225
  <span class="ruby-identifier">sum</span> = <span class="ruby-identifier">vals</span>.<span class="ruby-identifier">reduce</span>(<span class="ruby-value">0.0</span>) { <span class="ruby-operator">|</span><span class="ruby-identifier">running_total</span>, <span class="ruby-identifier">val</span><span class="ruby-operator">|</span>
214
226
  <span class="ruby-identifier">running_total</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">val</span>
@@ -246,7 +258,7 @@ href="BadConfigurationException.html">BadConfigurationException</a> if
246
258
 
247
259
 
248
260
  <div class="method-source-code" id="convert_clouds_to_use_to_array-source">
249
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 123</span>
261
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 138</span>
250
262
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">convert_clouds_to_use_to_array</span>(<span class="ruby-identifier">job</span>)
251
263
  <span class="ruby-identifier">clouds_class</span> = <span class="ruby-identifier">job</span>[<span class="ruby-value">:clouds_to_use</span>].<span class="ruby-identifier">class</span>
252
264
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">clouds_class</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Symbol</span>
@@ -290,7 +302,7 @@ standard format for Neptune jobs.</p>
290
302
 
291
303
 
292
304
  <div class="method-source-code" id="ensure_all_jobs_are_hashes-source">
293
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 95</span>
305
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 110</span>
294
306
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ensure_all_jobs_are_hashes</span>(<span class="ruby-identifier">jobs</span>)
295
307
  <span class="ruby-identifier">jobs</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">job</span><span class="ruby-operator">|</span>
296
308
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">job</span>.<span class="ruby-identifier">class</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">Hash</span>
@@ -327,7 +339,7 @@ missing params.</p>
327
339
 
328
340
 
329
341
  <div class="method-source-code" id="ensure_all_params_are_present-source">
330
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 107</span>
342
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 122</span>
331
343
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ensure_all_params_are_present</span>(<span class="ruby-identifier">job</span>)
332
344
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">job</span>[<span class="ruby-value">:clouds_to_use</span>].<span class="ruby-identifier">nil?</span>
333
345
  <span class="ruby-identifier">raise</span> <span class="ruby-constant">BadConfigurationException</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&quot;:clouds_to_use was not specified&quot;</span>)
@@ -364,7 +376,7 @@ missing params.</p>
364
376
 
365
377
 
366
378
  <div class="method-source-code" id="ensure_credentials_are_in_correct_format-source">
367
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 165</span>
379
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 180</span>
368
380
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ensure_credentials_are_in_correct_format</span>(<span class="ruby-identifier">job</span>)
369
381
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">job</span>[<span class="ruby-value">:credentials</span>].<span class="ruby-identifier">nil?</span>
370
382
  <span class="ruby-identifier">raise</span> <span class="ruby-constant">BadConfigurationException</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&quot;No credentials were specified.&quot;</span>)
@@ -401,7 +413,7 @@ missing params.</p>
401
413
 
402
414
 
403
415
  <div class="method-source-code" id="find_optimal_cloud_for_task-source">
404
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 277</span>
416
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 325</span>
405
417
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">find_optimal_cloud_for_task</span>(<span class="ruby-identifier">job</span>, <span class="ruby-identifier">profiling_info</span>)
406
418
  <span class="ruby-identifier">raise</span> <span class="ruby-constant">NotImplementedError</span>
407
419
  <span class="ruby-keyword">end</span></pre>
@@ -431,7 +443,7 @@ missing params.</p>
431
443
 
432
444
 
433
445
  <div class="method-source-code" id="generate_babel_tasks-source">
434
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 282</span>
446
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 330</span>
435
447
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">generate_babel_tasks</span>(<span class="ruby-identifier">job</span>, <span class="ruby-identifier">clouds_to_run_task_on</span>)
436
448
  <span class="ruby-identifier">tasks</span> = []
437
449
 
@@ -480,7 +492,7 @@ missing params.</p>
480
492
 
481
493
 
482
494
  <div class="method-source-code" id="get_clouds_to_run_task_on-source">
483
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 227</span>
495
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 275</span>
484
496
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_clouds_to_run_task_on</span>(<span class="ruby-identifier">job</span>, <span class="ruby-identifier">profiling_info</span>)
485
497
  <span class="ruby-identifier">optimize_for</span> = <span class="ruby-identifier">job</span>[<span class="ruby-value">:optimize_for</span>]
486
498
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">optimize_for</span> <span class="ruby-operator">==</span> <span class="ruby-value">:performance</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">optimize_for</span> <span class="ruby-operator">==</span> <span class="ruby-value">:cost</span>
@@ -515,9 +527,9 @@ missing params.</p>
515
527
 
516
528
 
517
529
  <div class="method-source-code" id="get_key_from_job_data-source">
518
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 222</span>
530
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 270</span>
519
531
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_key_from_job_data</span>(<span class="ruby-identifier">job</span>)
520
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">job</span>[<span class="ruby-value">:code</span>]
532
+ <span class="ruby-keyword">return</span> <span class="ruby-identifier">job</span>[<span class="ruby-value">:code</span>].<span class="ruby-identifier">gsub</span>(<span class="ruby-regexp">%r[\/\.]/</span>, <span class="ruby-string">&quot;&quot;</span>)
521
533
  <span class="ruby-keyword">end</span></pre>
522
534
  </div><!-- get_key_from_job_data-source -->
523
535
 
@@ -545,7 +557,7 @@ missing params.</p>
545
557
 
546
558
 
547
559
  <div class="method-source-code" id="get_minimum_val_in_data-source">
548
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 237</span>
560
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 285</span>
549
561
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_minimum_val_in_data</span>(<span class="ruby-identifier">job</span>, <span class="ruby-identifier">profiling_info</span>)
550
562
  <span class="ruby-identifier">min_cloud</span> = <span class="ruby-keyword">nil</span>
551
563
  <span class="ruby-identifier">min_val</span> = <span class="ruby-value">1_000_000</span> <span class="ruby-comment"># infinity</span>
@@ -600,11 +612,44 @@ missing params.</p>
600
612
 
601
613
 
602
614
  <div class="method-source-code" id="get_profiling_info-source">
603
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 214</span>
615
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 229</span>
604
616
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_profiling_info</span>(<span class="ruby-identifier">job</span>)
605
617
  <span class="ruby-identifier">key</span> = <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_key_from_job_data</span>(<span class="ruby-identifier">job</span>)
606
- <span class="ruby-identifier">neptune_manager</span> = <span class="ruby-constant">BabelHelper</span>.<span class="ruby-identifier">get_neptune_manager_client</span>(<span class="ruby-identifier">job</span>)
607
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">neptune_manager</span>.<span class="ruby-identifier">get_profiling_info</span>(<span class="ruby-identifier">key</span>)
618
+
619
+ <span class="ruby-keyword">if</span> <span class="ruby-operator">!</span><span class="ruby-constant">File</span>.<span class="ruby-identifier">exists?</span>(<span class="ruby-constant">NEPTUNE_DATA_DIR</span>)
620
+ <span class="ruby-constant">FileUtils</span>.<span class="ruby-identifier">mkdir</span>(<span class="ruby-constant">NEPTUNE_DATA_DIR</span>)
621
+ <span class="ruby-keyword">end</span>
622
+
623
+ <span class="ruby-identifier">profiling_info_file</span> = <span class="ruby-node">&quot;#{NEPTUNE_DATA_DIR}/#{key}.json&quot;</span>
624
+ <span class="ruby-keyword">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">exists?</span>(<span class="ruby-identifier">profiling_info_file</span>)
625
+ <span class="ruby-identifier">contents</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">profiling_info_file</span>) { <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">read</span>() }
626
+ <span class="ruby-keyword">return</span> <span class="ruby-constant">JSON</span>.<span class="ruby-identifier">load</span>(<span class="ruby-identifier">contents</span>)
627
+ <span class="ruby-keyword">end</span>
628
+
629
+ <span class="ruby-comment"># If we don't have any profiling info on this job, run it locally and</span>
630
+ <span class="ruby-comment"># gather the data ourselves.</span>
631
+
632
+ <span class="ruby-identifier">start_time</span> = <span class="ruby-constant">Time</span>.<span class="ruby-identifier">now</span>
633
+ <span class="ruby-comment"># TODO(cgb): exec the user's code</span>
634
+ <span class="ruby-identifier">end_time</span> = <span class="ruby-constant">Time</span>.<span class="ruby-identifier">now</span>
635
+
636
+ <span class="ruby-comment"># To find out how fast this computer is, just check the file that has</span>
637
+ <span class="ruby-comment"># this info on it and take the first processor. This should be fine</span>
638
+ <span class="ruby-comment"># since we assume the user's code is not-multi-core aware and that</span>
639
+ <span class="ruby-comment"># all processors on this box are the same speed.</span>
640
+ <span class="ruby-identifier">cpu_speed</span> = <span class="ruby-constant">Float</span>(<span class="ruby-constant">CommonFunctions</span>.<span class="ruby-identifier">shell</span>(<span class="ruby-constant">GET_CPU_INFO</span>).
641
+ <span class="ruby-identifier">scan</span>(<span class="ruby-regexp">%rcpu MHz\s*:\s*(\d+\.\d+)/</span>).<span class="ruby-identifier">flatten</span>[<span class="ruby-value">0</span>])
642
+
643
+ <span class="ruby-identifier">json_info</span> = {
644
+ <span class="ruby-string">&quot;total_execution_time&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">end_time</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">start_time</span>,
645
+ <span class="ruby-string">&quot;cpu_speed&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">cpu_speed</span>
646
+ }
647
+
648
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">profiling_info_file</span>, <span class="ruby-string">&quot;w+&quot;</span>) { <span class="ruby-operator">|</span><span class="ruby-identifier">file</span><span class="ruby-operator">|</span>
649
+ <span class="ruby-identifier">file</span>.<span class="ruby-identifier">write</span>(<span class="ruby-constant">JSON</span>.<span class="ruby-identifier">dump</span>(<span class="ruby-identifier">json_info</span>))
650
+ }
651
+
652
+ <span class="ruby-keyword">return</span> <span class="ruby-identifier">json_info</span>
608
653
  <span class="ruby-keyword">end</span></pre>
609
654
  </div><!-- get_profiling_info-source -->
610
655
 
@@ -634,7 +679,7 @@ the job does not specify it.</p>
634
679
 
635
680
 
636
681
  <div class="method-source-code" id="propogate_credentials_from_environment-source">
637
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 180</span>
682
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 195</span>
638
683
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">propogate_credentials_from_environment</span>(<span class="ruby-identifier">job</span>)
639
684
  <span class="ruby-constant">CLOUD_CREDENTIALS</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">cloud_name</span>, <span class="ruby-identifier">credential_list</span><span class="ruby-operator">|</span>
640
685
  <span class="ruby-identifier">credential_list</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">cred</span><span class="ruby-operator">|</span>
@@ -670,7 +715,7 @@ the job does not specify it.</p>
670
715
 
671
716
 
672
717
  <div class="method-source-code" id="run_job-source">
673
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 306</span>
718
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 354</span>
674
719
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">run_job</span>(<span class="ruby-identifier">tasks_to_run</span>)
675
720
  <span class="ruby-keyword">return</span> <span class="ruby-identifier">babel</span>(<span class="ruby-identifier">tasks_to_run</span>)
676
721
  <span class="ruby-keyword">end</span></pre>
@@ -702,7 +747,7 @@ credentials needed to use that cloud.</p>
702
747
 
703
748
 
704
749
  <div class="method-source-code" id="validate_clouds_to_use-source">
705
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 144</span>
750
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 159</span>
706
751
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">validate_clouds_to_use</span>(<span class="ruby-identifier">job</span>)
707
752
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ensure_credentials_are_in_correct_format</span>(<span class="ruby-identifier">job</span>)
708
753
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">propogate_credentials_from_environment</span>(<span class="ruby-identifier">job</span>)
@@ -748,7 +793,7 @@ credentials needed to use that cloud.</p>
748
793
 
749
794
 
750
795
  <div class="method-source-code" id="validate_files_argv_executable-source">
751
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 205</span>
796
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 220</span>
752
797
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">validate_files_argv_executable</span>(<span class="ruby-identifier">job</span>)
753
798
  [<span class="ruby-value">:code</span>, <span class="ruby-value">:argv</span>, <span class="ruby-value">:executable</span>].<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">param</span><span class="ruby-operator">|</span>
754
799
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">job</span>[<span class="ruby-identifier">param</span>].<span class="ruby-identifier">nil?</span>
@@ -782,7 +827,7 @@ credentials needed to use that cloud.</p>
782
827
 
783
828
 
784
829
  <div class="method-source-code" id="validate_optimize_for_param-source">
785
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 191</span>
830
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 206</span>
786
831
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">validate_optimize_for_param</span>(<span class="ruby-identifier">job</span>)
787
832
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">job</span>[<span class="ruby-value">:optimize_for</span>].<span class="ruby-identifier">nil?</span>
788
833
  <span class="ruby-identifier">raise</span> <span class="ruby-constant">BadConfigurationException</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&quot;:optimize_for needs to be &quot;</span> <span class="ruby-operator">+</span>
@@ -186,7 +186,7 @@ indicates whether or not the compilation was successful.</p>
186
186
 
187
187
 
188
188
  <div class="method-source-code" id="compile_code-source">
189
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 458</span>
189
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 459</span>
190
190
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">compile_code</span>(<span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">ssh_args</span>, <span class="ruby-identifier">shadow_ip</span>)
191
191
  <span class="ruby-identifier">compiled_location</span> = <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">compile_code</span>(<span class="ruby-identifier">job_data</span>)
192
192
  <span class="ruby-identifier">copy_to</span> = <span class="ruby-identifier">job_data</span>[<span class="ruby-string">&quot;@copy_to&quot;</span>]
@@ -278,7 +278,7 @@ job succeeded and if it failed, the reason for it.</p>
278
278
 
279
279
 
280
280
  <div class="method-source-code" id="get_input-source">
281
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 406</span>
281
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 407</span>
282
282
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_input</span>(<span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">ssh_args</span>, <span class="ruby-identifier">shadow_ip</span>, <span class="ruby-identifier">controller</span>)
283
283
  <span class="ruby-identifier">result</span> = {<span class="ruby-value">:result</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">:success</span>}
284
284
 
@@ -335,7 +335,7 @@ NeptuneManager.</p>
335
335
 
336
336
 
337
337
  <div class="method-source-code" id="get_job_data-source">
338
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 313</span>
338
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 314</span>
339
339
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_job_data</span>(<span class="ruby-identifier">params</span>)
340
340
  <span class="ruby-identifier">job_data</span> = {}
341
341
  <span class="ruby-identifier">params</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">k</span>, <span class="ruby-identifier">v</span><span class="ruby-operator">|</span>
@@ -411,7 +411,7 @@ not the job completed successfully (success = no errors).</p>
411
411
 
412
412
 
413
413
  <div class="method-source-code" id="get_std_out_and_err-source">
414
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 486</span>
414
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 487</span>
415
415
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">get_std_out_and_err</span>(<span class="ruby-identifier">location</span>)
416
416
  <span class="ruby-identifier">result</span> = {}
417
417
 
@@ -458,7 +458,7 @@ engines can be found by contacting an AppScale node.</p>
458
458
 
459
459
 
460
460
  <div class="method-source-code" id="preprocess_babel-source">
461
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 261</span>
461
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 262</span>
462
462
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">preprocess_babel</span>(<span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">controller</span>)
463
463
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">require_param</span>(<span class="ruby-string">&quot;@code&quot;</span>, <span class="ruby-identifier">job_data</span>)
464
464
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">require_param</span>(<span class="ruby-string">&quot;@engine&quot;</span>, <span class="ruby-identifier">job_data</span>)
@@ -731,7 +731,8 @@ it does not, throws an exception.</p>
731
731
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">does_file_exist?</span>(<span class="ruby-identifier">file</span>, <span class="ruby-identifier">job_data</span>)
732
732
  <span class="ruby-keyword">return</span>
733
733
  <span class="ruby-keyword">else</span>
734
- <span class="ruby-identifier">raise</span> <span class="ruby-constant">FileNotFoundException</span>
734
+ <span class="ruby-identifier">raise</span> <span class="ruby-constant">FileNotFoundException</span>.<span class="ruby-identifier">new</span>(<span class="ruby-node">&quot;Expecting file #{file} to exist &quot;</span> <span class="ruby-operator">+</span>
735
+ <span class="ruby-string">&quot;in the remote datastore, which did not exist.&quot;</span>)
735
736
  <span class="ruby-keyword">end</span>
736
737
  <span class="ruby-keyword">end</span></pre>
737
738
  </div><!-- require_file_to_exist-source -->
@@ -762,7 +763,7 @@ raising an exception if the named file does exist.</p>
762
763
 
763
764
 
764
765
  <div class="method-source-code" id="require_file_to_not_exist-source">
765
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 246</span>
766
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 247</span>
766
767
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">require_file_to_not_exist</span>(<span class="ruby-identifier">file</span>, <span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">controller</span>)
767
768
  <span class="ruby-keyword">begin</span>
768
769
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">require_file_to_exist</span>(<span class="ruby-identifier">file</span>, <span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">controller</span>)
@@ -832,7 +833,7 @@ as well as information about the node to send the request to.</p>
832
833
 
833
834
 
834
835
  <div class="method-source-code" id="run_job-source">
835
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 536</span>
836
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 537</span>
836
837
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">run_job</span>(<span class="ruby-identifier">job_data</span>, <span class="ruby-identifier">ssh_args</span>, <span class="ruby-identifier">shadow_ip</span>, <span class="ruby-identifier">secret</span>)
837
838
  <span class="ruby-identifier">controller</span> = <span class="ruby-constant">NeptuneManagerClient</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">shadow_ip</span>, <span class="ruby-identifier">secret</span>)
838
839
 
@@ -893,7 +894,7 @@ with Cicero jobs. It requires the AppScale tools to be installed.</p>
893
894
 
894
895
 
895
896
  <div class="method-source-code" id="upload_app_for_cicero-source">
896
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 507</span>
897
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 508</span>
897
898
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">upload_app_for_cicero</span>(<span class="ruby-identifier">job_data</span>)
898
899
  <span class="ruby-keyword">if</span> <span class="ruby-operator">!</span><span class="ruby-identifier">job_data</span>[<span class="ruby-string">&quot;@app&quot;</span>]
899
900
  <span class="ruby-comment"># Kernel.puts &quot;No app specified, not uploading...&quot; </span>
@@ -948,7 +949,7 @@ parameter is missing.</p>
948
949
 
949
950
 
950
951
  <div class="method-source-code" id="validate_storage_params-source">
951
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 366</span>
952
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 367</span>
952
953
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">validate_storage_params</span>(<span class="ruby-identifier">job_data</span>)
953
954
  <span class="ruby-identifier">job_data</span>[<span class="ruby-string">&quot;@storage&quot;</span>] <span class="ruby-operator">||=</span> <span class="ruby-string">&quot;appdb&quot;</span>
954
955
 
@@ -1012,7 +1013,7 @@ location.</p>
1012
1013
 
1013
1014
 
1014
1015
  <div class="method-source-code" id="wait_for_compilation_to_finish-source">
1015
- <pre><span class="ruby-comment"># File lib/neptune.rb, line 437</span>
1016
+ <pre><span class="ruby-comment"># File lib/neptune.rb, line 438</span>
1016
1017
  <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">wait_for_compilation_to_finish</span>(<span class="ruby-identifier">ssh_args</span>, <span class="ruby-identifier">shadow_ip</span>, <span class="ruby-identifier">compiled_location</span>)
1017
1018
  <span class="ruby-identifier">loop</span> {
1018
1019
  <span class="ruby-identifier">ssh_command</span> = <span class="ruby-node">&quot;ssh #{ssh_args} root@#{shadow_ip} 'ls #{compiled_location}' 2&gt;&amp;1&quot;</span>
@@ -329,7 +329,7 @@ select the best cloud for their job and run it there.</p>
329
329
 
330
330
 
331
331
  <div class="method-source-code" id="exodus-source">
332
- <pre><span class="ruby-comment"># File lib/exodus.rb, line 15</span>
332
+ <pre><span class="ruby-comment"># File lib/exodus.rb, line 20</span>
333
333
  <span class="ruby-keyword">def</span> <span class="ruby-identifier">exodus</span>(<span class="ruby-identifier">jobs</span>)
334
334
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">jobs</span>.<span class="ruby-identifier">class</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Hash</span>
335
335
  <span class="ruby-identifier">job_given_as_hash</span> = <span class="ruby-keyword">true</span>
@@ -1,10 +1,10 @@
1
- Mon, 30 Jul 2012 17:12:01 -0700
2
- bin/neptune Sun, 12 Feb 2012 16:12:33 -0800
3
- lib/exodus.rb Mon, 28 May 2012 21:02:31 -0700
4
- lib/task_info.rb Mon, 28 May 2012 16:24:14 -0700
5
- lib/babel.rb Mon, 30 Jul 2012 17:10:06 -0700
6
- lib/neptune_manager_client.rb Mon, 04 Jun 2012 13:53:07 -0700
7
- lib/common_functions.rb Sun, 12 Feb 2012 16:18:14 -0800
8
- lib/neptune.rb Mon, 30 Jul 2012 17:09:09 -0700
1
+ Fri, 28 Sep 2012 13:17:21 -0700
2
+ lib/babel.rb Sat, 01 Sep 2012 13:14:23 -0700
3
+ lib/exodus.rb Tue, 25 Sep 2012 12:38:28 -0700
9
4
  lib/custom_exceptions.rb Mon, 28 May 2012 16:23:52 -0700
10
- lib/exodus_task_info.rb Mon, 28 May 2012 21:03:03 -0700
5
+ lib/neptune_manager_client.rb Sat, 01 Sep 2012 13:14:23 -0700
6
+ lib/exodus_task_info.rb Mon, 30 Jul 2012 17:40:12 -0700
7
+ lib/common_functions.rb Sat, 01 Sep 2012 13:14:23 -0700
8
+ lib/neptune.rb Fri, 28 Sep 2012 13:12:58 -0700
9
+ lib/task_info.rb Mon, 28 May 2012 16:24:14 -0700
10
+ bin/neptune Sat, 01 Sep 2012 13:14:23 -0700
@@ -119,10 +119,10 @@
119
119
 
120
120
  <li class="method"><a href="ExodusTaskInfo.html#method-c-new">::new &mdash; ExodusTaskInfo</a>
121
121
 
122
- <li class="method"><a href="NeptuneManagerClient.html#method-c-new">::new &mdash; NeptuneManagerClient</a>
123
-
124
122
  <li class="method"><a href="TaskInfo.html#method-c-new">::new &mdash; TaskInfo</a>
125
123
 
124
+ <li class="method"><a href="NeptuneManagerClient.html#method-c-new">::new &mdash; NeptuneManagerClient</a>
125
+
126
126
  <li class="method"><a href="NeptuneHelper.html#method-c-preprocess_babel">::preprocess_babel &mdash; NeptuneHelper</a>
127
127
 
128
128
  <li class="method"><a href="NeptuneHelper.html#method-c-preprocess_compile">::preprocess_compile &mdash; NeptuneHelper</a>
@@ -147,12 +147,12 @@
147
147
 
148
148
  <li class="method"><a href="NeptuneHelper.html#method-c-require_param">::require_param &mdash; NeptuneHelper</a>
149
149
 
150
+ <li class="method"><a href="ExodusHelper.html#method-c-run_job">::run_job &mdash; ExodusHelper</a>
151
+
150
152
  <li class="method"><a href="BabelHelper.html#method-c-run_job">::run_job &mdash; BabelHelper</a>
151
153
 
152
154
  <li class="method"><a href="NeptuneHelper.html#method-c-run_job">::run_job &mdash; NeptuneHelper</a>
153
155
 
154
- <li class="method"><a href="ExodusHelper.html#method-c-run_job">::run_job &mdash; ExodusHelper</a>
155
-
156
156
  <li class="method"><a href="CommonFunctions.html#method-c-scp_file">::scp_file &mdash; CommonFunctions</a>
157
157
 
158
158
  <li class="method"><a href="CommonFunctions.html#method-c-scp_to_shadow">::scp_to_shadow &mdash; CommonFunctions</a>
@@ -211,10 +211,10 @@
211
211
 
212
212
  <li class="method"><a href="TaskInfo.html#method-i-to_json">#to_json &mdash; TaskInfo</a>
213
213
 
214
- <li class="method"><a href="ExodusTaskInfo.html#method-i-to_s">#to_s &mdash; ExodusTaskInfo</a>
215
-
216
214
  <li class="method"><a href="TaskInfo.html#method-i-to_s">#to_s &mdash; TaskInfo</a>
217
215
 
216
+ <li class="method"><a href="ExodusTaskInfo.html#method-i-to_s">#to_s &mdash; ExodusTaskInfo</a>
217
+
218
218
  </ul>
219
219
 
220
220
 
@@ -2,7 +2,12 @@
2
2
  # Programmer: Chris Bunch
3
3
 
4
4
 
5
+ require 'rubygems'
6
+ require 'json'
7
+
8
+
5
9
  require 'babel'
10
+ require 'common_functions'
6
11
  require 'custom_exceptions'
7
12
  require 'exodus_task_info'
8
13
 
@@ -87,6 +92,16 @@ module ExodusHelper
87
92
  }
88
93
 
89
94
 
95
+ # The location on this machine where we can read and write profiling
96
+ # information about jobs.
97
+ NEPTUNE_DATA_DIR = File.expand_path("~/.neptune")
98
+
99
+
100
+ # The command that we can run to get information about the number and speed
101
+ # of CPUs on this machine.
102
+ GET_CPU_INFO = "cat /proc/cpuinfo"
103
+
104
+
90
105
  OPTIMIZE_FOR_CHOICES = [:performance, :cost, :auto]
91
106
 
92
107
 
@@ -213,14 +228,47 @@ module ExodusHelper
213
228
 
214
229
  def self.get_profiling_info(job)
215
230
  key = self.get_key_from_job_data(job)
216
- neptune_manager = BabelHelper.get_neptune_manager_client(job)
217
- return neptune_manager.get_profiling_info(key)
231
+
232
+ if !File.exists?(NEPTUNE_DATA_DIR)
233
+ FileUtils.mkdir(NEPTUNE_DATA_DIR)
234
+ end
235
+
236
+ profiling_info_file = "#{NEPTUNE_DATA_DIR}/#{key}.json"
237
+ if File.exists?(profiling_info_file)
238
+ contents = File.open(profiling_info_file) { |f| f.read() }
239
+ return JSON.load(contents)
240
+ end
241
+
242
+ # If we don't have any profiling info on this job, run it locally and
243
+ # gather the data ourselves.
244
+
245
+ start_time = Time.now
246
+ # TODO(cgb): exec the user's code
247
+ end_time = Time.now
248
+
249
+ # To find out how fast this computer is, just check the file that has
250
+ # this info on it and take the first processor. This should be fine
251
+ # since we assume the user's code is not-multi-core aware and that
252
+ # all processors on this box are the same speed.
253
+ cpu_speed = Float(CommonFunctions.shell(GET_CPU_INFO).
254
+ scan(/cpu MHz\s*:\s*(\d+\.\d+)/).flatten[0])
255
+
256
+ json_info = {
257
+ "total_execution_time" => end_time - start_time,
258
+ "cpu_speed" => cpu_speed
259
+ }
260
+
261
+ File.open(profiling_info_file, "w+") { |file|
262
+ file.write(JSON.dump(json_info))
263
+ }
264
+
265
+ return json_info
218
266
  end
219
267
 
220
268
 
221
269
  # TODO(cgb): what is a job's key?
222
270
  def self.get_key_from_job_data(job)
223
- return job[:code]
271
+ return job[:code].gsub(/[\/\.]/, "")
224
272
  end
225
273
 
226
274
 
@@ -236,7 +236,8 @@ module NeptuneHelper
236
236
  if controller.does_file_exist?(file, job_data)
237
237
  return
238
238
  else
239
- raise FileNotFoundException
239
+ raise FileNotFoundException.new("Expecting file #{file} to exist " +
240
+ "in the remote datastore, which did not exist.")
240
241
  end
241
242
  end
242
243
 
@@ -36,6 +36,8 @@ class TestExodus < Test::Unit::TestCase
36
36
  :S3_URL => "http://s3.url",
37
37
  :S3_bucket_name => "bazbucket"
38
38
  }
39
+
40
+ flexmock(FileUtils).should_receive(:mkdir).and_return()
39
41
  end
40
42
 
41
43
 
@@ -223,16 +225,38 @@ class TestExodus < Test::Unit::TestCase
223
225
  :executable => "ruby"
224
226
  }
225
227
 
226
- # mock out the SOAP call for get_profiling_info
227
- no_job_data = {
228
- }
229
- flexmock(NeptuneManagerClient).new_instances { |instance|
230
- instance.should_receive(:get_profiling_info).with(job[:code]).
231
- and_return(no_job_data)
232
- }
228
+ # let's say they've never run an exodus job before, so they have
229
+ # no profiling data stored locally
230
+ flexmock(File).should_receive(:exists?).
231
+ with(ExodusHelper::NEPTUNE_DATA_DIR).and_return(false)
232
+ flexmock(FileUtils).should_receive(:mkdir).
233
+ with(ExodusHelper::NEPTUNE_DATA_DIR).and_return()
234
+
235
+ # mock out the gathering of profiling info
236
+ profiling_filename = "#{ExodusHelper::NEPTUNE_DATA_DIR}/#{ExodusHelper.get_key_from_job_data(job)}.json"
237
+ flexmock(File).should_receive(:exists?).
238
+ with(profiling_filename).and_return(false)
239
+
240
+ # mock out timing the user's code
241
+ flexmock(Time).should_receive(:now).and_return(1.0, 2.0)
233
242
 
234
- profiling_info = ExodusHelper.get_profiling_info(job)
235
- assert_equal(true, profiling_info.empty?)
243
+ # then mock out exec'ing the user's code
244
+ # TODO(cgb): do this
245
+
246
+ # mock out getting cpuinfo
247
+ flexmock(CommonFunctions).should_receive(:shell).
248
+ with(ExodusHelper::GET_CPU_INFO).and_return("cpu MHz: 666.66")
249
+
250
+ # finally, mock out writing the profiling information
251
+ flexmock(File).should_receive(:open).with(profiling_filename, "w+", Proc).
252
+ and_return()
253
+
254
+ expected = {
255
+ "total_execution_time" => 1.0,
256
+ "cpu_speed" => 666.66
257
+ }
258
+ actual = ExodusHelper.get_profiling_info(job)
259
+ assert_equal(expected, actual)
236
260
  end
237
261
 
238
262
 
@@ -526,10 +550,6 @@ class TestExodus < Test::Unit::TestCase
526
550
 
527
551
  # mock out calls to the NeptuneManager
528
552
  flexmock(NeptuneManagerClient).new_instances { |instance|
529
- # for this test, let's say there's no data on this task right now
530
- instance.should_receive(:get_profiling_info).with(String).
531
- and_return({})
532
-
533
553
  # let's say that all checks to see if temp files exist tell us that
534
554
  # the files don't exist
535
555
  instance.should_receive(:does_file_exist?).
@@ -562,6 +582,31 @@ class TestExodus < Test::Unit::TestCase
562
582
  # we'll say that our code does exist
563
583
  flexmock(File).should_receive(:exists?).with("/foo").and_return(true)
564
584
 
585
+ # let's say that we have a neptune profiling directory
586
+ flexmock(File).should_receive(:exists?).
587
+ with(ExodusHelper::NEPTUNE_DATA_DIR).and_return(true)
588
+
589
+ # and let's say that we've never run the job before
590
+ # start by mocking out its filesystem reads
591
+ key = ExodusHelper.get_key_from_job_data(job)
592
+ profiling_key = "#{ExodusHelper::NEPTUNE_DATA_DIR}/#{key}.json"
593
+ flexmock(File).should_receive(:exists?).
594
+ with(profiling_key).and_return(false)
595
+
596
+ # mock out timing the user's code
597
+ flexmock(Time).should_receive(:now).and_return(1.0, 2.0)
598
+
599
+ # then mock out exec'ing the user's code
600
+ # TODO(cgb): do this
601
+
602
+ # mock out getting cpuinfo
603
+ flexmock(CommonFunctions).should_receive(:shell).
604
+ with(ExodusHelper::GET_CPU_INFO).and_return("cpu MHz: 666.66")
605
+
606
+ # finally, mock out writing the profiling information
607
+ flexmock(File).should_receive(:open).with(profiling_key, "w+", Proc).
608
+ and_return()
609
+
565
610
  # mock out scp calls - assume they go through with no problems
566
611
  flexmock(CommonFunctions).should_receive(:shell).with(/\Ascp/).
567
612
  and_return()
@@ -605,12 +650,24 @@ class TestExodus < Test::Unit::TestCase
605
650
 
606
651
  job2 = job.dup
607
652
 
653
+ # let's say that we have a neptune profiling directory
654
+ flexmock(File).should_receive(:exists?).
655
+ with(ExodusHelper::NEPTUNE_DATA_DIR).and_return(true)
656
+
657
+ # and let's say that we've run the job before
658
+ key = ExodusHelper.get_key_from_job_data(job)
659
+ profiling_filename = "#{ExodusHelper::NEPTUNE_DATA_DIR}/#{key}.json"
660
+ dumped_data = JSON.dump({
661
+ "total_execution_time" => 60.00,
662
+ "cpu_speed" => 666.66
663
+ })
664
+ flexmock(File).should_receive(:exists?).
665
+ with(profiling_filename).and_return(true)
666
+ flexmock(File).should_receive(:open).
667
+ with(profiling_filename, Proc).and_return(dumped_data)
668
+
608
669
  # mock out calls to the NeptuneManager
609
670
  flexmock(NeptuneManagerClient).new_instances { |instance|
610
- # for this test, let's say there's no data on this task right now
611
- instance.should_receive(:get_profiling_info).with(String).
612
- and_return({})
613
-
614
671
  # let's say that all checks to see if temp files exist tell us that
615
672
  # the files don't exist
616
673
  instance.should_receive(:does_file_exist?).
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neptune
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 2
10
- version: 0.2.2
9
+ - 3
10
+ version: 0.2.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Bunch
@@ -15,7 +15,7 @@ autorequire: neptune
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-07-31 00:00:00 Z
18
+ date: 2012-09-28 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: promise