challenge 分散関数呼び出し

分散関数呼び出しを実装してください.

呼び出される関数は,定価を整数で,割引率(%)を整数で受け取り,
文字列で「販売価格 ○円(定価○円から○%引き)」を返すものとします.
また,数字は3桁のカンマ区切りにするものとします.

たとえば,pricestring(2000, 20) なら
"販売価格 1,600円 (定価2,000円から20%引き)"
を返します.

関数の呼び出し元と,呼び出される側は,物理的に異なる
サーバに配置できることを条件とします.
呼び出し方法は問いませんが,呼び出し方法に名前がある場合,
それをタグに加えてください.
(XML-RPC,SOAP,CORBA,RMI,など)

また,作成した関数を直列に1万回呼び出して,
実行にかかった時間を測定してください.
測定時は別サーバでなくても構いません.
(なるべく別サーバが望ましいです)

測定環境として,
・サーバとクライアントのCPU・メモリ
・同一サーバ内での実行か別サーバでの実行か
・別サーバの場合,通信経路.(100Mbps Ethernet等)
・言語のバージョン
・ミドルウェアを使用している場合,その名前とバージョン
も併記してください.

1つの言語で複数の分散関数呼び出しの実装方法がある場合,
複数の回答を歓迎します.

出題の意図は,様々な分散呼び出し方法の実装例と,
レスポンス速度の確認にあります.
このお題は沢渡 みかげさんの投稿です。 まったく手を加えないでいい完成度の投稿で本当に助かります。 ありがとうございました。

Posted feedbacks - C

C言語 + libxmlrpc(サーバーは apache 経由のCGI)で実装しました。
サーバーサイドのスペック
* Celeron 1.3GHz
* メモリ1G
* xmlrpc-c-1.11.00
11.285 秒でした

最初はシリアルに問い合わせてみたのですが目も当てられないぐらい遅かったので非同期dで 100発 × 100回 というようにパラレルに問い合わせるようにしました。
あとは apache のチューニングでもう少し早くなりそうです。(prefork だったので)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* サーバー側 CGIコード */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<xmlrpc.h>
#include<xmlrpc_cgi.h>

static void int2cstr(int num, char *str)
{
    int i, j;
    char buf[16];
    size_t len;
    snprintf(buf, sizeof(buf), "%d", num);
    len = strlen(buf);
    for(i=j=0; i<len; i++){
        str[j++] = buf[i];
        if(i != len - 1 && (len - i - 1) % 3 == 0) str[j++] = ',';
    }
    str[j] = '\0';
}

static xmlrpc_value *pricestring(xmlrpc_env *env, xmlrpc_value *param_array,
                                 void *user_data)
{
    xmlrpc_int32 price, discount;
    int value;
    char str[256], value_str[16], price_str[16];

    xmlrpc_parse_value(env, param_array, "(ii)", &price, &discount);
    if(env->fault_occurred) return NULL;
    value = price - (price * discount / 100);

    int2cstr(price, price_str);
    int2cstr(value, value_str);
    snprintf(str, sizeof(str),
             "販売価格 %s円 (定価%s円から%d%引き)",
             value_str, price_str, discount);
    return xmlrpc_build_value(env, "s", str);
}

int main (int argc, char **argv)
{
    xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS);
    xmlrpc_cgi_add_method_w_doc("pricestring", &pricestring, NULL,
                                "s:ii", "Add two integers.");
    xmlrpc_cgi_process_call();
    xmlrpc_cgi_cleanup();
    return EXIT_SUCCESS;
}

/* クライアント側コード */
#include <stdio.h>
#include <stdlib.h>
#include <xmlrpc.h>
#include <xmlrpc_client.h>

#define XMLRPC_URL "http://192.168.0.13/pricestring.cgi"

static void print_state_name_callback (char *server_url,
                       char *method_name,
                       xmlrpc_value *param_array,
                       void *user_data,
                       xmlrpc_env *env,
                       xmlrpc_value *result)
{
    char *str;
    if(env->fault_occurred) return;
    xmlrpc_parse_value(env, result, "s", &str);
    if(env->fault_occurred) return;
    printf("%s\n", str);
}

int main (int argc, char **argv)
{
    int i, j;
    
    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NULL, NULL);
    for(i = 0; i < 100; i++){
        for(j = 0; j < 100; j++){
            xmlrpc_client_call_asynch(XMLRPC_URL, "pricestring",
                                      print_state_name_callback, NULL,
                                      "(ii)",
                                      (xmlrpc_int32)2000, (xmlrpc_int32)20);
        }
        xmlrpc_client_event_loop_finish_asynch();
    }
    xmlrpc_client_cleanup();
    return 0;
}

Index

Feed

Other

Link

Pathtraq

loading...