Version 8 (modified by 17 years ago) (diff) | ,
---|
Bossa reference manual
Bossa is a framework for distributed thinking applications. We'll describe Bossa using an example. The example shows users pictures of zeros or ones, and asks the user to identify the number.
Database tables
Until Bossa has good web-based administration tools, you'll often need to directly examine and modify its MySQL database, using the command-line tool 'mysql' or a web-based interface such as phpMyAdmin.
The database tables used by Bossa (in addition to BOINC's tables for users, teams, etc.) are as follows:
bossa_app:
field name | type | meaning |
id | integer | row ID, assigned by MySQL |
create_time | integer | row creation time |
name | varchar(255) | short name (internal use; no spaces) |
user_friendly_name | varchar(255) | user-visible name (spaces OK) |
long_jobs | tinyint | nonzero if user can have > 1 active job |
start_url | varchar(255) | name (relative to project URL) of start script |
deprecated | tinyint | nonzero if deprecated (don't show) |
info | text | information (typically encoded in JSON) such as the criteria for which users to issue jobs to |
bossa_job:
field name | type | meaning |
id | integer | row ID, assigned by MySQL |
create_time | integer | row creation time |
name | varchar(255) | a unique name for this job |
app_id | integer | ID of bossa_app |
info | text | job-specific info (file names etc.) typically JSON-encoded |
batch | integer | batch number (use to group jobs) |
time_estimate | integer | number of seconds this job is likely to take |
time_limit | integer | give up if not completed after this number of seconds |
more_needed | tinyint | nonzero if more completed instances of this job are needed |
npending | integer | number of pending instances |
nsuccess | integer | number of successfully completed instances |
nsuccess_needed | integer | required number of successfully completed instances |
bossa_job_inst:
field name | type | meaning |
id | integer | row ID, assigned by MySQL |
create_time | integer | row creation time |
job_id | integer | ID of bossa_job |
user_id | integer | ID of user |
finish_time | integer | time when finished, or zero |
info | text | outcome info (usually JSON-encoded) |
bossa_app_user:
app_id | integer | ID of bossa_app |
user_id | integer | ID of user |
info | text | description of the user's skill or ranking at a given app, typically JSON-encoded |
Bossa PHP classes
Bossa provides the following classes (in html/inc/bossa.inc and html/inc/bossa_db.inc):
- BossaApp, BossaJob, BossaJobInst
- These correspond to the above tables, and have fields corresponding to each database field. They offer functions to insert, look up, and modify database rows.
- Bossa
- Utility functions.
Creating a Bossa project
First, set up a BOINC server and create a project. You'll need PHP 5.2 or later (for JSON functions). Say your project is called test_project, your BOINC source directory is ~/boinc, and your BOINC projects directory is ~/projects.
Create Bossa's database tables as follows:
cd ~/boinc/db mysql test_project < bossa_schema.sql mysql test_project < bossa_constraints.sql
Create a Bossa application as follows:
cd ~/projects/test_project/html/ops php bossa_setup_example.php
bossa_setup_example.php contains:
$ba = new BossaApp(); $ba->name = 'bossa_test'; $ba->user_friendly_name = 'Simple pattern recognition'; $ba->start_url = 'bossa_example.php'; if ($ba->insert($ba)) { echo "Added application '$ba->name'\n"; } else { echo "Couldn't add '$ba->name': ", mysql_error(), "\n"; }
You can edit this to change the application name and front-end script name, if you like.
Adding jobs
Typically you'll add jobs using a script. Here's an example (html/ops/bossa_make_jobs_example.php):
1 <?php 2 3 require_once("../inc/bossa_db.inc"); 4 require_once("../inc/db.inc"); 5 6 db_init(); 7 8 function make_jobs() { 9 $appname = 'bossa_test'; 10 $app = BossaApp::lookup_name($appname); 11 if (!$app) { 12 echo "Application $appname not found\n"; 13 exit(1); 14 } 15 $job = new BossaJob; 16 $job->app_id = $app->id; 17 $job->batch = 0; 18 $job->time_estimate = 30; 19 $job->time_limit = 600; 20 $job->nsuccess_needed = 3; 21 for ($i=0; $i<10; $i++) { 22 $job->name = "job_$i"; 23 $info = null; 24 $info->number = $i % 2; 25 $job->info = json_encode($info); 26 if (!$job->insert()) { 27 echo "BossaJob::insert failed: ", mysql_error(), "\n"; 28 exit(1); 29 } 30 } 31 } 32 33 make_jobs(); 34 echo "All done.\n"; 35 36 ?>
This creates 10 jobs. Each job has an info field consisting of a JSON-encoded structure consisting of an integer (0 or 1).
Front-end scripts
You develop a front-end script to show a job instance to a user, and to handle a completed instance. It's handy to put both of these functions in a single file. A front-end script is called with the URL parameter bji set to a job instance ID. Here's an example (html/user/bossa_example.php):
1 <?php 2 3 require_once("../inc/bossa.inc"); 4 5 echo "foo"; 6 7 // Bossa example. 8 // Show the user an image and ask them whether it's a zero or one. 9 10 function show_job($bj, $bji) { 11 if ($bji->finish_time) { 12 error_page("You already finished this job"); 13 } 14 $info = json_decode($bj->info); 15 $img_url = "http://boinc.berkeley.edu/images/number_".$info->number.".jpg"; 16 echo " 17 <form method=get action=bossa_example.php> 18 <input type=hidden name=bji value=$bji->id> 19 <img src=$img_url> 20 <br> 21 The picture shows a 22 <br><input type=radio name=response value=0> zero 23 <br><input type=radio name=response value=1> one 24 <br><input type=radio name=response value=2 checked> not sure 25 <br><br><input type=submit name=submit value=OK> 26 </form> 27 "; 28 } 29 30 function handle_job_completion($bj, $bji) { 31 $response = null; 32 $response->number = get_int('response'); 33 $bji->info = json_encode($response); 34 $bji->completed($bj); 35 36 // show another job immediately 37 // 38 Bossa::show_next_job($bj); 39 } 40 41 Bossa::script_init($user, $bj, $bji); 42 43 if ($_GET['submit']) { 44 handle_job_completion($bj, $bji); 45 } else { 46 show_job($bj, $bji); 47 } 48 49 ?>
- Line 41
- Call a Bossa utility function to look up the job instance and make sure that it was issued to the logged-in user. The job instance, job, and user are returned.
- Line 43
- Branch according to whether we are showing a job or handling the completion of a job.
- Line 14
- If we're showing a job, decode its info structure to decide whether to show which picture to show.
- Lines 17-18
- Task completion will be handled by this script; arrange to pass the job instance ID.
- Lines 31-33
- Get the user's response, and encode it in JSON.
- Line 34
- Call a utility function that marks the job instance as completed and updates its database record.
- Line 38
- Call a utility function that gets another job (if one is available) and shows it to the user.