Distributed Computing Class Library

· Home

· Download
      libdccl-1.0.0.tar.gz

· Documentation

· News archive

  

Documentation

Installation

The simplest way to install DCCL on your system is as follows:
  • tar xzf libdccl-version.tar.gz (untar the source package)
  • cd libdccl-version
  • ./configure
  • make
  • make install (as root)
This will compile the sources and will install the libraries and header files into the standard directories. You can also use the --prefix=dir option to specify another installation directory (e.g. --prefix=/tmp/dccl will install the header files into /tmp/dccl/include and the libraries into /tmp/dcl/lib).

Compiling your programs

If your programs are using DCCL and you did set a non standard directory during the configure process you have to tell the compiler where to look for the header files and the library. For gcc the directory for the header files is set with the option "-Idirectory". If you want to link your programs against the shared version of DCCL you have add "-Ldirectory -ldccl" to the compiler flags. If you want to use the static version just add "directory/libdccl.a" when linking your program.
For example, if you have installed DCCL into /tmp/dccl than you can compile your sources as follows:

g++ -I/tmp/dccl/include -L/tmp/dccl/lib -ldccl main.cc -o main (shared)
or
g++ -I/tmp/dccl/include /tmp/dccl/libdccl.a main.cc -o main (static)

Writing a master

Writing a master is quiet easy and the basic steps will be demonstrated by the following example.
 1 #include "master.hh"
 2 #include "client.hh"
 3 #include <iostream>
 4 #include <vector>

 5 #define CMD_PORT  17200
 6 #define HTTP_PORT 17280

 7 bool _quit = false;

 8 class mymaster : public master
 9 {
10 public:
11    mymaster() : master( CMD_PORT, HTTP_PORT ) {
12    }
13    virtual void result( int jobid, int status, void* buf, int len ) {
14        std::cout << "got result for " << jobid << " " << status << " " << len << std::endl;
15        // do something with the result
16        // when being in this method further incoming results are accepted and will be scheduled
17        // until the method is left
18        free( buf );
19        _quit = true;
20    }
21 };

22 int main( int argc, char** argv )
23 {
24    mymaster* m = new mymaster();
25    std::vector< client* > v;
26    while( v.empty() ) { // wait for at least one slave to become available
27        sleep( 1 );
28        m->get_clients( v );
29    }
30    char* s = "hello slave\n";
31    // use the first slave to add the job with jobid 23
32    if( m->add_job( v[ 0 ], s, strlen( s ) + 1, 23 ) ) {
33        std::cout << "waiting for result..." << std::endl;
34        while( ! _quit ) sleep( 1 );
35    } else {
36        std::cerr << "could not add job" << std::endl;
37    }
38 }
As shown in this example to write a master process first you have write a class that is derived from the class master and which implements the abstract method result. This is done in line 8 to 21. The method result is called whenever a result for a job has been received or when an error has been occurred for some job. The status can either be OK or ERR. The result is stored in buf and the length of the result is given by len. On error buf is set to NULL. The constructor of master is given the ports where to listen for pings and results and for http connections. The default is 17200 for pings and results and 17280 for http connections.
To get a list of slaves the master provides the method get_clients which returns a vector of pointers to slaves. This vector can be used to find a slave that fits to a jobs. The class client provides the following methods.

Return typeMethodDescription
u_int64_tram()Returns the size of the RAM in bytes.
doublebogo()Returns the number of bogomips of one CPU.
doubleload()Returns the last reported load.
time_tlastping()Returns the timestamp of the last received ping.

If an appropriate slave has been found a job can be added to that client by using the master's method add_job which is given the client pointer as first argument, the data of the job as second argument, the size of the data as third argument and an jobid as fourth argument. If the job has been successfully sent to the slave true is returned, otherwise false.

Writing a slave

Writing a slave is as easy as writing a master and the basic steps will be demonstrated by the following example.
 1 #include "slave.hh"
 2 #include "slaveworkerthread.hh"
 3 #include <iostream>

 4 class myworker : public slaveworkerthread
 5 {
 6 public:
 7     myworker() {
 8     }
 9     virtual char* exec( int& len ) {
10         std::cout << "got job" << std::endl;
11         std::cout << siz() << std::endl << buf() << std::endl;
12         len = 13;
13         return strdup( "hello master" );
14     }
15 };

16 class myslave : public slave
17 {
18 public:
19     myslave() : slave( "localhost" ) {
20     }
21     virtual slaveworkerthread* data() {
22         return (slaveworkerthread*) new myworker();
23     }
24 };

25 int main( int argc, char** argv )
26 {
27     myslave* s = new myslave();
28     while( true ) {
29         sleep( 1 );
30     }
31 }
To write a slave at least two classes have to be written which are derived from the abstract classes slaveworkerthread which is responsible for executing a job and slave which receives a job, creates a worker thread, executes this thread and sends the result to the master.
The constructor of slave is given the address of the master as first argument and optionally the port of the master as second argument. The default value for the port is set to 17200. The slave's port can be given as third argument (default: 17201) and the ping interval in seconds as fourth argument (default: 5s).
The abstract method data of slave is called whenever a new job has been received. It must resturn an instance of slaveworkerthread which implements the abstract method exec and executes the jobs. Each derived class of slaveworkerthread inherits the method buf() which returns a character pointer to the data of the received job and the method siz() which returns the size of the data. The result must be returned as a character pointer and the size of the data must be written to len.