Friday, February 5, 2010

Moving code execution from client to server

This post replies to this question from the comments.

There are two ways to move the execution of some code from client to server. Choosing one way or another depends on the purpose and complexity of the code to be moved.

Simple way - static server method.
This one is applicable when the code to be executed on server does not affect owning object's state. For example, if MyClass class has the following method run() :
public void run()
{
    while select forupdate table1
    {
        table1.Field1 = instanceMember1;
        table1.Field2 = instanceMember2;
        table1.update();
    }
}
The code depends on the object state – instanceMember1 and instanceMember2, but does not modify it. In this case code can be rewritten in the following way.
public void run()
{
    MyClass::runOnServer(instanceMember1, instanceMember2);
}
private static server void runOnServer(SomeType1 _arg1, SomeType2 _arg2)
{
    while select forupdate table1
    {
        table1.Field1 = _arg1;
        table1.Field2 = _arg2;
        table1.update();
    }
}

Complex way – serialization.
This one should be used when the job to be moved on server modifies object state. In this case the client-side object should be serialized to some data structure -package (for example, container in the standard pack\unpack serialization approach). Then a new instance of the same class as client-side object should be created on the server and de-serialized from the package – so we get exactly the same objects on client and server. After that the job should be executed on the server-side object. Then server-side object is serialized to a package and client-side object (the initial one) is de-serialized from the package. So, the client-side and server-side objects are the same again with the state as it should be after job execution.
Example:
public void run()
{
    while select forupdate table1
    {
        table1.Field1 = instanceMember1;
        table1.Field2 = instanceMember2;
        instanceMember1 += 1;
        instanceMember2 += 2;
        table1.update();
    }
}
Will be rewritten as:
public void run()
{
    MyClass myClassOnServer;
    if (!isRunningOnServer())
    {
        myClassOnServer = MyClass::constructOnServer();
        myClassOnServer.unpack(this.pack());
        myClassOnServer.run();
        this.unpack(myClassOnServer.pack());
    }
    else
    {
        while select forupdate table1
        {
            table1.Field1 = instanceMember1;
            table1.Field2 = instanceMember2;
            instanceMember1 += 1;
            instanceMember2 += 2;
            table1.update();
        }
    }
}
public static server MyClass constructOnServer()
{
    return new MyClass();
}
public container pack()
{
    return [instanceMember1, instanceMember2];
}
public void unpack(container _packedClass)
{
    instanceMember1 = conpeek(_packedClass, 1);
    instanceMember2 = conpeek(_packedClass, 2);
}
Note, that in this example there will be 4 client-server RPC calls: call of constructOnServer(), unpack(), run() and pack() methods. This number can be reduced to only one call by wrapping all the calls by server static method but in the example it wasn’t done for better readability.

11 comments:

  1. Perfect, thanks for the explanation.

    ReplyDelete
  2. I used your first approach because my method takes two parameter dates and inserts rows into a table using those parameter dates, without changing them in any way.

    However, the following statement in the "server static MyMethod" method shows that it is running on the client.

    info(strfmt("Running on: %1", Global::clientKind()));

    What gives?

    ReplyDelete
  3. No FlаmingHave busineѕѕ уou ever been flameԁ
    for flаmed ѕomeοne else? She says shе doeѕn't" even know where she wants to see business CDR s and many other emotions. Besides that, a set of beliefs that a group policy will abolish the need for extensive IT services business whether from in-house personnel or consultants. Calculate the employee's Medіcarе tаx.
    Food contaіners and ρlаteѕ аre cool
    tоо. Get coaching on how tо close it.


    My ѕite calgary internet marketing

    ReplyDelete
  4. Hi to every body, it's my first paay a quick
    visit of this web site; this websie carries amazing and in fact good information in favor of visitors.



    Here is my website; iphone icloud bypass

    ReplyDelete
  5. just about issues? Everybody loves to economise wealth online.
    It is really "in" these days is treat medical aid.
    mete out all that you get quicker results.

    A new attorney to design past. The to the highest degree tight performing of selling
    your clarity should be as efficient in disreputable areas.
    Beareas cognizant of one's defrayal Wholesale Jerseys Jerseys China Cheap NHL Jerseys Jerseys China World Cup Jerseys NHL Jerseys Cheap Jerseys China China Jerseys Jerseys China NFL Cheap Jerseys Jerseys China Cheap Soccer Jerseys
    Wholesale Jerseys China NFL Cheap Jerseys Jerseys China Wholesale Jerseys China Jerseys China
    Cheap NBA Jerseys Cheap Soccer Jerseys Cheap NFL Jerseys Cheap MLB Jerseys
    Jersyes China Jerseys China Wholesale Jerseys China Jerseys Wholesale city mercantilism.
    go across bound you advertize yourself. do it a tilt of your drive.
    If you see in that respect's a lot of tranquillity of opinion. exploitation this oblige
    can be a go away of your mobile twist. Although it's
    not that punishing and you may not usually expression in. see much time

    ReplyDelete
  6. If you need your ex-girlfriend or ex-boyfriend to come crawling back to you on their knees (even if they're dating somebody else now) you must watch this video
    right away...

    (VIDEO) Why your ex will NEVER come back...

    ReplyDelete