Sample Remote Component Call Code

 

Using Luban’s reflection mechanism and network streaming facilities, it is almost trivial to construct a client/server tool to enable remote calling of Luban components. On the client side, all need to be done is to send the component name, input property values plus the desired output property names. For the server, it needs to listen to the incoming connection get the component name, inputs and desired output names. Server then builds the component by name, set its inputs, get its output as required and send results back through the same socket. The whole system can be built with very little Luban code. That’s why we can list the whole system code as in less than two pages below.

 

1           Remote Component Call Server Code

 

// a multi-threaded RCC server

namespace luban::demo;

 

struct RCCServer( store readwrite int port;)

as process

{

            rootlistener = net::listener(store.port);

            while ( true )

            {

                        onesock = rootlistener.accept(); // receive incoming call

                        ::HandleRCC(socket=onesock) &  // dispatch to a different thread

            }

}

 

// HandleRCC actually handle one call and return results

struct HandleRCC

(

            input:

                        socket;

)

as process

{

            socket = input.socket;

            package = socket.readobj(); // get the whole package

 

            compname = package[0]; // first one is component name

            args = package[1]; // second one input properties

            resultprps = package[2]  //third one for desired outputs;

 

            comp = luban::ns().create(compname); // construct by reflection

            comp.pset(args);  // property setting by reflection

            result = comp.pget(resultprps); // property get by reflection

 

            socket.writeobj(result);

}

 

There are two struct are defined in above code. One is the main loop of the RCC server, all it does is to listen to the incoming connection and dispatch to the struct HandleRCC in a different thread then back to listening again. Thread dispatching is a common technique used in server coding to accommodate more than one request simultaneously.

In the struct HandleRCC, a package is retrieved from socket. And component name, inputs and desired outputs are unpacked. Then using reflection mechanism, component is built, its inputs are set and outputs are gotten. Then the results are written back to the same socket.

 

2           Remote Component Call Client Code

 

// Remote Component Call client code

namespace luban::demo;

 

struct RCCClient

(

            store readwrite int port; store readwrite string host;

            input:

                        string compname;

                        map     ins;

                        outs;

            output  results;

)

as process

{

                        onesock = net::socket(store.host, store.port);

                        onesock.writeobj(  [input.compname,  input.ins,  input.outs ] );

                        output.results = onesock.readobj();

}

 

The RCC client code is even simpler. All it does it to make a connection to the specified server host and port. Then client put user specified component name, inputs and desired outputs into a package of vector format, write to the socket. The last step is simply waiting for the results to come back from server.

 

3           How to Run RCC Server and Client

The below line of Luban script will start the RCC server at port 9600.

 

            luban::demo::RCCServer(port=9600);

 

The below several lines of code dispatch the work separated to multiple parts and send them simultaneously to the server and wait for them to finish.

 

            client = luban::demo::RCCClient();

            client.host = “superserver.mycompany.com”;

            client.port = 9600;

            P1=client(compname=”myns::supercalc” , inputs={“vectosum”:[1,2,3,4]}, outs=”sumofvec”).results &

            P2= client(compname=”myns::supercalc”, inputs={“vectosum”:[5,6,7,8]}, outs=”sumofvec”).results &

            P3 = client(compname=”myns::supercalc”, inputs={“vectosum”:[9,10,11,12]}, outs=”sumofvec”).results &

            waitfor P1,P2,P3;

            total = P1+P2+P3;

 

Above code construct a RCC client to talk the server running on “superserver.mycompany.com” at port 9600. Through the connection, client calls the component named “myns::supercalc” to summarize numbers in a vector. It dispatches three calls in different thread to summarize three vectors simultaneously, wait for them to come back. Finally it then adds up the three results to get the grand total.

 

4           Possible Improvements of Sample RCC

Using reflection and networking, we build a very practical and useful RCC client/server system. There many ways to improve it in practice. One straight forward way is to run the RCC server on a virtual server that may dispatch jobs to a server cluster. Since cluster can probably handle the load balancing by itself, it is transparent to Luban user. For Luban user the unlimited power of parallel computer is now available at their finger tips.

 

5           Reflection and Parallel Computing: A Perfect Match

From above example RCC system, we can see that it is powerful to combine reflection and parallel network computing together in Luban. Luban makes a perfect environment to dispatch parallel jobs and synchronize them. With Luban, you have the infinite capacity of cheap computing power from server farm. You can attach problem of any complexity as far as the problem itself can be divided and conquered as smaller problems.