|
|
|
## Overview:
|
|
|
|
|
|
|
|
##### 1\. Where is the code to fill out the mustache template, main.sh.mustache, and do the qsub to the batch system?
|
|
|
|
|
|
|
|
The relevant mustache code is in the osc-machete project, in lib/osc/machete/location.rb.
|
|
|
|
|
|
|
|
Similarly, the qsub command is issued via the OSC::Machete::TorqueHelper object in lib/osc/machete/torque_helper.rb.
|
|
|
|
|
|
|
|
##### 2\. I see a submit method in controllers/simulations_controller.rb, but don't follow it. Also wondering what the format.html vs. format.json statements are for?
|
|
|
|
|
|
|
|
Rails provides ways to render to different formats/targets. Two of those are HTML and JSON. A normal web request with a browser will be served the HTML format, while a browser making an AJAX request will get the JSON format. In the controller, you specify what to serve in either case.
|
|
|
|
|
|
|
|
##### 3\. For simulations using input files/decks, where is the "staging area" in the filesystem?
|
|
|
|
|
|
|
|
The staging area is in the ~/crimson_files directory in the user’s home directory.
|
|
|
|
|
|
|
|
## Details
|
|
|
|
|
|
|
|
### Mustache gem
|
|
|
|
|
|
|
|
The mustache gem is installed in ruby-2.0.0-p247 and you can use it directly:
|
|
|
|
|
|
|
|
```
|
|
|
|
-bash-3.2$ gem list mustache
|
|
|
|
|
|
|
|
*** LOCAL GEMS ***
|
|
|
|
|
|
|
|
mustache (0.99.5)
|
|
|
|
|
|
|
|
-bash-3.2$ irb
|
|
|
|
irb(main):001:0> require 'mustache'
|
|
|
|
=> true
|
|
|
|
irb(main):002:0> Mustache.render "My name is {{name}}", name: "Eric"
|
|
|
|
=> "My name is Eric"
|
|
|
|
irb(main):003:0>
|
|
|
|
```
|
|
|
|
|
|
|
|
In `osc-machete` we use mustache in `location.rb` to recursively render and rename the template files in a similar fashion as is done with the Sprockets Rails asset pipeline (http://guides.rubyonrails.org/asset_pipeline.html and https://github.com/rails/sprockets-rails).
|
|
|
|
|
|
|
|
### Flow of action for SimulationsController#submit in HelloSim
|
|
|
|
|
|
|
|
config/routes.rb has this:
|
|
|
|
|
|
|
|
HelloSim::Application.routes.draw do
|
|
|
|
scope 'hello' do
|
|
|
|
resources :simulations do
|
|
|
|
member do
|
|
|
|
get 'submit'
|
|
|
|
get 'results', :defaults => { :format => 'pdf' }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
root 'simulations#index'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Notice the get 'submit'. That is a member route added to the simulation resource so that it is accessible via simulations/1/submit where 1 is the db id of the simulation.
|
|
|
|
|
|
|
|
In the root of the app you can type
|
|
|
|
|
|
|
|
rake routes
|
|
|
|
|
|
|
|
To see a list of all the routes, the URI pattern, and the resulting controller/action that is called:
|
|
|
|
|
|
|
|
```
|
|
|
|
Prefix Verb URI Pattern Controller#Action
|
|
|
|
submit_simulation GET /hello/simulations/:id/submit(.:format) simulations#submit
|
|
|
|
```
|
|
|
|
|
|
|
|
In the near future we will fix the fact that this is a GET request instead of a PUT request (POST + some magic javascript via Rails to add `_method=PUT` making the request from the view is how Rails supports other HTTP Verbs that browsers typically don't work with). Regardless you can see that making a request to /hello/simulations/1/submit would call SimulationsController#submit with the params hash to have the id set to 1.
|
|
|
|
|
|
|
|
When submit is called, in SimulationsController, line 2 has this:
|
|
|
|
|
|
|
|
before_action :set_simulation, only: [:show, :edit, :update, :destroy, :submit, :results]
|
|
|
|
|
|
|
|
This says, before the action method is called, call "set_simulation" method, but only for the specified actions (show, edit etc.). Submit is in that list. So before submit is called set_simulation is called, which just sets the @simulation instance variable:
|
|
|
|
|
|
|
|
@simulation = Simulation.find(params[:id])
|
|
|
|
|
|
|
|
If we made a request to request to /hello/simulations/1/submit, `params[:id]` would be 1 and the `@simulation` variable would get the instance of Simulation populated with data from the corresponding row in that database.
|
|
|
|
|
|
|
|
Now the method submit is called. Since the instance variable @simulation is set, we can just use it. Simulation includes the module `OSC::Machete::SimpleJob` as a mixin, which adds a bunch of methods to Simulation, including submitted? and submit(params). So in `SimulationsController#submit`, first I check to make sure that the simulation hasn't already been submitted, and if it has return an error message:
|
|
|
|
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
if @simulation.submitted?
|
|
|
|
respond_to do |format|
|
|
|
|
format.html { redirect_to simulations_url, alert: 'Simulation has already been submitted!' }
|
|
|
|
format.json { head :no_content }
|
|
|
|
end
|
|
|
|
else
|
|
|
|
```
|
|
|
|
|
|
|
|
If it hasn't been submitted, then I call `@simulation.submit(@simulation.serializable_hash)`. The code for this method is in `OSC::Machete::SimpleJob`.
|
|
|
|
|
|
|
|
|
|
|
|
`@simulation.serializable_hash` just returns a hash of all the attributes names and their values which is what the submit function wants. This is SimpleJob#submit:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
def submit(params)
|
|
|
|
# stage and submit job
|
|
|
|
job = staging.new_job params
|
|
|
|
job.submit
|
|
|
|
|
|
|
|
# persist job data
|
|
|
|
self.status = job.status
|
|
|
|
self.pbsid = job.pbsid
|
|
|
|
self.job_path = job.path.to_s
|
|
|
|
self.save
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
Notice staging here is a function call to `SimpleJob#staging`, job is a Job object created by the Staging class we returned, and the last section is setting the attributes on self (which in HelloSim's case is the instance of Simulation) and then calling save, which is tantamount to doing:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
@simulation.status = job.status
|
|
|
|
@simulation.pbsid = job.pbsid
|
|
|
|
@simulation.job_path = job.path.to_s
|
|
|
|
@simulation.save
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Example of using Machete directly via irb
|
|
|
|
|
|
|
|
osc-machete is now installed system wide so you can just `require 'osc/machete'` to use the latest version of the gem:
|
|
|
|
|
|
|
|
```
|
|
|
|
-bash-3.2$ irb -rosc/machete
|
|
|
|
irb(main):009:0> j = OSC::Machete::Job.new pbsid: "2601223.oak-batch.osc.edu"
|
|
|
|
=> #<OSC::Machete::Job:0x002b861b94b340 @pbsid="2601223.oak-batch.osc.edu", @torque=#<OSC::Machete::TorqueHelper:0x002b861b94b318>>
|
|
|
|
irb(main):010:0> j.status
|
|
|
|
=> :R
|
|
|
|
```
|
|
|
|
|
|
|
|
Or you could write your own ruby script that that does something using the gem:
|
|
|
|
|
|
|
|
```
|
|
|
|
-bash-3.2$ cat test.rb
|
|
|
|
require 'osc/machete'
|
|
|
|
|
|
|
|
pbsid = "2601268.oak-batch.osc.edu"
|
|
|
|
j = OSC::Machete::Job.new pbsid: pbsid
|
|
|
|
puts j.status
|
|
|
|
```
|
|
|
|
|
|
|
|
And then run it like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
-bash-3.2$ ruby test.rb
|
|
|
|
Q
|
|
|
|
-bash-3.2$
|
|
|
|
``` |