Example #1
0
int client_test(o2_message_ptr data, const char *types,
                o2_arg_ptr *argv, int argc, void *user_data)
{
    o2_send(server_addresses[msg_count % N_ADDRS], 0, "i", msg_count);
    if (msg_count % 10000 == 0) {
        printf("client received %d messages\n", msg_count);
    }
    msg_count++;
    return O2_SUCCESS;
}
Example #2
0
// o2_ping_send_handler -- handler for /_o2/ps (short for "ping send")
//   wait for clock sync service to be established,
//   then send ping every 0.1s CLOCK_SYNC_HISTORY_LEN times, 
//   then every 0.5s for 5s, then every 10s
//
void o2_ping_send_handler(o2_msg_data_ptr msg, const char *types,
                          o2_arg_ptr *argv, int argc, void *user_data)
{
    // this function gets called periodically to drive the clock sync
    // protocol, but if the process calls o2_clock_set(), then we
    // become the master, at which time we stop polling and announce
    // to all other processes that we know what time it is, and we
    // return without scheduling another callback.
    if (is_master) {
        o2_clock_is_synchronized = TRUE;
        return; // no clock sync; we're the master
    }
    clock_sync_send_time = o2_local_time();
    int status = o2_status("_cs");
    if (!found_clock_service) {
        found_clock_service = (status >= 0);
        if (found_clock_service) {
            O2_DBc(printf("%s ** found clock service, is_master=%d\n",
                          o2_debug_prefix, is_master));
            if (status == O2_LOCAL || status == O2_LOCAL_NOTIME) {
                assert(is_master);
            } else { // record when we started to send clock sync messages
                start_sync_time = clock_sync_send_time;
                char path[48]; // enough room for !IP:PORT/cs/get-reply
                snprintf(path, 48, "!%s/cs/get-reply",
                         o2_context->process->proc.name);
                o2_method_new(path, "it", &cs_ping_reply_handler,
                              NULL, FALSE, FALSE);
                snprintf(path, 32, "!%s/cs", o2_context->process->proc.name);
                clock_sync_reply_to = o2_heapify(path);
            }
        }
    }
    // earliest time to call this action again is clock_sync_send_time + 0.1s:
    o2_time when = clock_sync_send_time + 0.1;
    if (found_clock_service) { // found service, but it's non-local
        if (status < 0) { // we lost the clock service, resume looking for it
            found_clock_service = FALSE;
        } else {
            clock_sync_id++;
            o2_send("!_cs/get", 0, "is", clock_sync_id, clock_sync_reply_to); // TODO: test return?
            // run every 0.1 second until at least CLOCK_SYNC_HISTORY_LEN pings
            // have been sent to get a fast start, then ping every 0.5s until 5s,
            // then every 10s.
            o2_time t1 = CLOCK_SYNC_HISTORY_LEN * 0.1 - 0.01;
            if (clock_sync_send_time - start_sync_time > t1) when += 0.4;
            if (clock_sync_send_time - start_sync_time > 5.0) when += 9.5;
            O2_DBk(printf("%s clock request sent at %g\n",
                          o2_debug_prefix, clock_sync_send_time));
        }
    }
    // schedule another call to o2_ping_send_handler
    o2_clock_ping_at(when);
}
Example #3
0
void o2_clockrt_handler(o2_msg_data_ptr msg, const char *types,
                            o2_arg_ptr *argv, int argc, void *user_data)
{
    o2_extract_start(msg);
    o2_arg_ptr reply_to_arg = o2_get_next('s');
    if (!reply_to_arg) return;
    char *replyto = reply_to_arg->s;
    int len = (int) strlen(replyto);
    if (len > 1000) {
        fprintf(stderr, "o2_clockrt_handler ignoring /cs/rt message with long reply_to argument\n");
        return; // address too long - ignore it
    }
    char address[1024];
    memcpy(address, replyto, len);
    memcpy(address + len, "/get-reply", 11); // include EOS
    o2_send(address, 0, "sff", o2_context->process->proc.name, mean_rtt, min_rtt);
}
Example #4
0
int main(int argc, const char * argv[]) {
    o2_initialize("test");
    o2_add_service("client");
    
    for (int i = 0; i < N_ADDRS; i++) {
        char path[100];
        sprintf(path, "/client/benchmark/%d", i);
        o2_add_method(path, "i", &client_test, NULL, FALSE, FALSE);
    }
    
    for (int i = 0; i < N_ADDRS; i++) {
        char path[100];
        sprintf(path, "!server/benchmark/%d", i);
        server_addresses[i] = (char *) O2_MALLOC(strlen(path));
        strcpy(server_addresses[i], path);
    }
    
    while (o2_status("server") < O2_LOCAL) {
        o2_poll();
        usleep(2000); // 2ms
    }
    printf("We discovered the server.\ntime is %g.\n", o2_get_time());
    
    double now = o2_get_time();
    while (o2_get_time() < now + 5) {
        o2_poll();
        usleep(2000);
    }
    
    printf("Here we go! ...\ntime is %g.\n", o2_get_time());
    
    o2_send("!server/benchmark/0", 0, "i", 0);
    
    while (1) {
        o2_poll();
        //usleep(2000); // 2ms // as fast as possible
    }

    o2_finish();
    return 0;
}
Example #5
0
// cs_ping_handler -- handler for /_cs/get
//   return the master clock time. Arguments are serial_no and reply_to.
//   send serial_no and current time to serial_no + "/get-reply"
static void cs_ping_handler(o2_msg_data_ptr msg, const char *types,
                     o2_arg_ptr *argv, int argc, void *user_data)
{
    o2_arg_ptr serial_no_arg, reply_to_arg;
    o2_extract_start(msg);
    if (!(serial_no_arg = o2_get_next('i')) ||
        !(reply_to_arg = o2_get_next('s'))) {
        return;
    }
    int serial_no = serial_no_arg->i32;
    char *replyto = reply_to_arg->s;
    int len = (int) strlen(replyto);
    if (len > 1000) {
        fprintf(stderr, "cs_ping_handler ignoring /_cs/get message with long reply_to argument\n");
        return; // address too long - ignore it
    }
    char address[1024];
    memcpy(address, replyto, len);
    memcpy(address + len, "/get-reply", 11); // include EOS
    o2_send(address, 0, "it", serial_no, o2_time_get());
}