Building a Whole new service#

Ideally you should only really need to add new analyses to the 2 existing services; sequence processing and structure processing. But maybe in the future we'd like to handle nucleotide sequence or something.

1) STARTING A NEW SERVICE Create a new controller and view for your service. I'll use the psipred server as a good template

scripts/generate controller [SERVICE] index


scripts/generate controller psipred index

This creates a range of files but the ones of real interest are the SERVICE_controller.rb and the ones in views/SERVICE/ (you'll not there is a page called index.rhtml in there already)

Our new app now has an index page.

To be honest this step is better achieved by just creating the controller and view files that you need by hand in netbeans, that way netbeans immediately knows they exist and will add them to CVS when you committ

Next create you new form in the views/SERVICE/index.rhtml file. You could do this easily by copying the views/psipred/index.rhml and editing it to your satisfaction. It is imperative for this guide that the form's action remains submit (see the top of the page). You'll find a full discussion of the form_tags syntax for creating form elements in any decent Rails reference

We'll also want a page to tell people that they've successfully submitted a job to our service. Create submit.rhtml in the views/SERVICE directory.Better yet you could copy over the psipred submit.rhtml and edit it to your end.

Next we want to edit the controller. The controller brokers the movement of data between the web front end and the database and backend server. It would be a good idea to copy the contents psipred server's psipred_controller.rb into your ap's controller. This provides 2 simple functions index and submit. When someone goes to you service the index function is called. This doesn't do much but it will render the index.rhtml you wrote and they'll see the webform. The submit function is called when a user sends data with the form (the form's action from point 2 above). Both these functions provide a @service_name variable, this must be present in both and you should edit it to the service name you used when you ran the generate controller in point 1 above.

The submit function handles the job submission logic:

i) It starts by calling a new instance of the job model object. It then populates the mandatory fields for the object with data coming from your submission form.

QueryString - expects and amino acid sequence using only valid single letter code\\
address - the email address for the the user - this is non mandatory\\
name - a job name the user has provided, this is mandatory\\
Type - a server name, this is the name of the backend server that will be called and should probably be the name for the service you provided in 1)
ii) Next there is some validation logic for commercial clients and email addresses we don't accept submissions from. Commercial clients may not apply to your service and you can comment this out.
iii) The next bit uses the job type (the service name) to associate with a default server configuration for your service (see 6 below)
iv) lastly the "respond_to do" statment calls the model, which validates the incoming data (see 5 below) and puts the job data in the database before submiting the job to the backend server. It is here that you can also change the type of response that your server omits, such as providing XML rather than HTML for webservices

The job model includes some validation checks for incoming data such as protein sequence and email address. If any of these fail the controller will hand the user the form again and with the appropriate warnings. For now QueryString, :Type and :name are mandatory fields for a job. The job class DOES NOT handle or store other configuration options that your service might allow the user to set in the input form (i.e. user settable config). These are handed straight to the backend service as key:value pairs when a job is submitted to the backend.

Also go to line 244 of the job.rb and add your service name to the list of services that won't be returning an email.

Your service needs a default configuration.
i) Go to
ii) Select "New Configuration"
iii) Under name enter your service name as per 1 (it is case sensitive).
iv) Enter a brief description
v) In the large box enter your server's configuration options as key:value pairs delimited by a ": ", i.e:

TDB_DIR: /var/www/cgi-bin/psipred/tdb/\\
BlastDB: /var/www/cgi-bin/psipred/data/

Your configuration should include paths to all the data or binaries that your service will use. It is imperative that the code you write for your backend server DOES NOT include any hard coded paths. The configuration is here to handle that. You should also include defaults settings parameters.

When naming your configuration options think carefully and use verbose descriptive names i.e. PSIPRED_WEIGHTS_DIR is better than WEIGHTS. This will make it easier for you and others to debug in the future.

Your config should set default values for all configurable options in your server. However your service's front end form will probably give the user some options they can set. In order for the user's input to over ride your defaults you must ensure that the appropriate form element ids should match with the identically named config key in your configuration. Prior to job submission (the job_submit command in your configuration) you need to save each of your overrides out to to the job_config_overrides table.

8) The backend server. The code for this is in the NewPredServer repository. The OldmGenJob is a good example of a simple running job. Make your server reasonably verbose, reporting what it's doing back to the command line. It should at least throw a message to stdout for every task it performs. I would also suggest that it throws the command it's trying to run too as this will help you debug it or allow others to follow what's going on in the future. After every step that produces results that you want to display online you need to pass those results back up to the ruby front end db, the UpdateStatus method allows you to achieve this, StatusClass and StatusCodes can be found in Most status codes are self explanatory

A server job ( in it's run method typically goes through the same steps. Initially it retrieves the configuration data in the m_config vector that has been passed to it from the front end database. Next it sets up a series of filehandles for all the temp files it's going to generate and later clear up. Then it trys to run the various tasks for the jobs. The methods for the tasks can be found in, all the methods in that class that run process need to throw and appropriate exception, to be caught by the calling job class. ALL OF THEM!

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-1) was last changed on 13-Feb-2013 16:26 by UnknownAuthor