Esempio n. 1
0
// The worker thread function.
//
// worker - The worker.
//
// Returns 0 if successful.
void *sky_worker_run(void *_worker)
{
    int rc;
    uint32_t i;
    sky_worker *worker = (sky_worker*)_worker;
    sky_worklet *worklet = NULL;
    check(worker != NULL, "Worker required");
    
    // Start benchmark.
    struct timeval tv;
    gettimeofday(&tv, NULL);
    int64_t t0 = (tv.tv_sec*1000) + (tv.tv_usec/1000);

    // Read data from stream.
    if(worker->read != NULL) {
        rc = worker->read(worker, worker->input);
        check(rc == 0, "Worker unable to read from stream");
    }

    // Push a message to each servlet.
    for(i=0; i<worker->push_socket_count; i++) {
        worklet = sky_worklet_create(worker); check_mem(worklet);
        rc = sky_zmq_send_ptr(worker->push_sockets[i], &worklet);
        check(rc == 0, "Worker unable to send worklet");
    }
    
    // Read in one pull message for every push message sent.
    for(i=0; i<worker->push_socket_count; i++) {
        // Receive worker back from servlet.
        rc = sky_zmq_recv_ptr(worker->pull_socket, (void**)&worklet);
        check(rc == 0 && worklet != NULL, "Worker unable to receive worklet");
        
        // Reduce worklet.
        if(worker->reduce != NULL) {
            rc = worker->reduce(worker, worklet->data);
            check(rc == 0, "Worker unable to reduce");
        }

        // Free worklet.
        if(worker->map_free) worker->map_free(worklet->data);
        worklet->data = NULL;
        sky_worklet_free(worklet);
        worklet = NULL;
    }
    
    // Output data to stream.
    if(worker->write != NULL) {
        rc = worker->write(worker, worker->output);
        check(rc == 0, "Worker unable to write output");
    }
    
    // End benchmark.
    gettimeofday(&tv, NULL);
    int64_t t1 = (tv.tv_sec*1000) + (tv.tv_usec/1000);
    printf("[worker] t=%.3fs\n", ((float)(t1-t0))/1000);
    
    // Clean up worker.
    worker->free(worker);
    sky_worker_free(worker);
    
    return NULL;

error:
    sky_worker_free(worker);
    return NULL;
}
Esempio n. 2
0
// Sends a shutdown signal to all servlets and waits for their confirmation
// before returning.
//
// server - The server.
// table  - The table to close servlets for. Or NULL if all servlets should be
//          closed.
//
// Returns 0 if successful, otherwise returns -1.
int sky_server_stop_servlets(sky_server *server, sky_table *table)
{
    int rc;
    void *pull_socket = NULL;
    void *push_socket = NULL;
    assert(server != NULL);

    // Create pull socket.
    pull_socket = zmq_socket(server->context, ZMQ_PULL);
    check(pull_socket != NULL, "Unable to create server shutdown socket");

    // Bind pull socket.
    rc = zmq_bind(pull_socket, SKY_SERVER_SHUTDOWN_URI);
    check(rc == 0, "Unable to bind server shutdown socket");

    // Send a shutdown message to each servlet.
    uint32_t i, j;
    uint32_t count = 0;
    for(i=0; i<server->servlet_count; i++) {
        // Check if this servlet matches the table.
        if(table == NULL || server->servlets[i]->tablet->table == table) {
            // Create push socket.
            push_socket = zmq_socket(server->context, ZMQ_PUSH);
            check(push_socket != NULL, "Unable to create shutdown push socket");
    
            // Connect to servlet.
            rc = zmq_connect(push_socket, bdata(server->servlets[i]->uri));
            check(rc == 0, "Unable to connect to servlet for shutdown");

            // Send NULL worklet for shutdown.
            void *ptr = NULL;
            rc = sky_zmq_send_ptr(push_socket, &ptr);
            check(rc == 0, "Unable to send worklet message");
        
            // Close socket.
            rc = zmq_close(push_socket);
            check(rc == 0, "Unable to close server shutdown push socket");
            push_socket = NULL;
            
            // Clear the servlet.
            for(j=i+1; j<server->servlet_count; j++) {
                server->servlets[j-1] = server->servlets[j];
            }
            server->servlets[server->servlet_count-1] = NULL;
            server->servlet_count--;
            i--;
            
            // Increment the counter.
            count++;
        }
    }

    // Read in one pull message for every push message sent.
    for(i=0; i<count; i++) {
        // Receive servlet ref on shutdown.
        sky_servlet *servlet = NULL;
        rc = sky_zmq_recv_ptr(pull_socket, (void**)&servlet);
        check(rc == 0, "Server unable to receive shutdown response");
    }

    // Clean up socket.
    rc = zmq_close(pull_socket);
    check(rc == 0, "Unable to close server shutdown pull socket");

    // Clean up servlets.
    if(server->servlet_count == 0) {
        free(server->servlets);
        server->servlets = NULL;
    }

    return 0;

error:
    if(pull_socket) zmq_close(pull_socket);
    if(push_socket) zmq_close(push_socket);
    return -1;
}