[sr-dev] mi vs RPC (was: xmlrpc interfaces)

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Jul 7 00:40:20 CEST 2009


On Jul 06, 2009 at 23:42, Daniel-Constantin Mierla <miconda at gmail.com> wrote:
[...]
> 
> this has to be worked out more.
> 
> The output is pre-formatted to be nicer displayed in sercmd, but 
> definitely cannot be used for xmlrpc transport. In K, mi tree can have 
> nodes with values and attributes. The attributes can have also values. 
> To be able to distinguish between nodes and attributes, I added +/-. 
> Also, some node names are missing, e.g., in 'which' command. A parameter 
> to control pretty formating along with mi command or a new command like 
> 'mi-pf' are options. Moreover, asynchronous mi command support is not 
> implemented.

What are attributes used for? I don't see them mapping to anything in
terms of xmlrpc or standard rpc.
Is anybody using the attributes?

What's that asynchronous command support? How can one use it using xmlrpc
(AFAIK xmlrpc does not support async. mode)? Is anybody using it?

> 
> Personally I don't think is time to remove any of the modules, because 
> we may get trapped in some limitations of the other one. We should 
> follow the usual path, decide which is better, if can handle everything 
> the other does, mark the other obsolete for one release and remove after 
> another release cycle.

We shouldn't remove anything now, but after the next release I don't see 
any reason for keeping mi (other then maybe some legacy application that
 uses some obscure feature).

Correct me if I'm wrong (I did only a quick code read):

mi_xmlrpc: 
- supports only strings as parameters
- responses are either one big string (reply_option=0) or
  one array of string values (reply_option=1). 

  For the first option (one big string) it kinds of defeats the purpose of
  XMLRPC. XMLRPC is an incredibly bloated and slow way of doing remote
  procedure calls, but at least is easy to use. You get the answer
  pre-parsed. However mi_rpc in one big string mode would require
  additional parsing of the big string to get individual values for any
  mi command returning a list (e.g. ps).

  For the second mode it always returns an array of string values, but this
  values look like: name:: value [attr_name=attr_value ...]. So again
  you'll have to do additional string parsing.

- cannot return integers
- cannot returns structures

xmlrpc(s) doesn't have any of the above limitations.
For example take core.tcp_info, an rpc that returns a structure with
 informations related to tcp:

sercmd> core.tcp_info 
{
    readers: 8
    max_connections: 2048
    opened_connections: 0
    write_queued_bytes: 0
}


Using xmlrpc from perl I can access the opened_connections with the 
following piece of perl code:

use XMLRPC::Lite;
my $res=XMLRPC::Lite ->proxy("http://127.0.0.1:5060")->call("core.tcp_info")
        ->result;
my %tcp_info=%{$res};
print "opened connections: $tcp_info{opened_connections}\n";

No extra parsing needed (try doing the same with a mi command).


In general to me MI looks too complex. It seems is more complex and more
 annoying to write then ser RPCs and does less...
RPC are easier to write, map perfectly on xmlrpc, support more types
then just plain strings and have integrated docs (try 
sercmd help <rpc_command> or sending system.methodHelp <rpc_command> over
xmlrpc).

Example:
The core.version rpc: (1 line of effective code)
static void core_version(rpc_t* rpc, void* c)
{
    rpc->add(c, "s", SERVER_HDR " " REPO_VER );
}


versus mi_version (modules_k/kex line 121): (28 lines of code excluding
 whitelines and defines, could be reduced to 20)
static struct mi_root *mi_version(struct mi_root *cmd, void *param)
{
    struct mi_root *rpl_tree;
    struct mi_node *rpl;
    struct mi_node *node;

    rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
    if (rpl_tree==0)
        return 0;
    rpl = &rpl_tree->node;

    node = add_mi_node_child( rpl, 0, MI_SSTR("Server"), SERVER_HDR+8,
        SERVER_HDR_LEN-8);
    if (node==0) 
        goto error;

    node = add_mi_node_child( rpl, 0, MI_SSTR("Build"), BUILD_STR,
            BUILD_STR_LEN);
    if (node==0) 
        goto error;

#ifndef KAMAILIO_COMPILE_FLAGS
#define KAMAILIO_COMPILE_FLAGS SER_COMPILE_FLAGS
#endif

    node = add_mi_node_child( rpl, 0, MI_SSTR("Flags"), KAMAILIO_COMPILE_FLAGS,
            sizeof(KAMAILIO_COMPILE_FLAGS)-1);
    if (node==0) 
        goto error; 
    
    node = add_mi_node_child( rpl, 0, MI_SSTR("SVN"), SVNREVISION,
            sizeof(SVNREVISION)-1);
    if (node==0) 
        goto error;

        
    
    return rpl_tree;
error:
    LM_ERR("failed to add node\n");
    free_mi_tree(rpl_tree);
    return 0;

}


> 
> I am more cautious to the changes done to things that interfaces with 
> the configuration file and mi/rpc transports, as these will break 
> installations and custom tools done by users, making migration nightmare.

I guess we have to find out how many custom tools there are out there that
 also process the responses of the mi commands (more then checking if the
 command succeeded or not).


Andrei



More information about the sr-dev mailing list