// Delegates processing of the 'Multi' message to a worker. // // server - The server. // header - The message header. // table - The table the message is working against // input - The input file stream. // output - The output file stream. // // Returns 0 if successful, otherwise returns -1. int sky_multi_message_process(sky_server *server, sky_message_header *header, sky_table *table, FILE *input, FILE *output) { int rc = 0; size_t sz; sky_multi_message *message = NULL; assert(header != NULL); assert(table == NULL); assert(input != NULL); assert(output != NULL); // Parse message. message = sky_multi_message_create(); check_mem(message); rc = sky_multi_message_unpack(message, input); check(rc == 0, "Unable to unpack 'multi' message"); // Send back an array header with the number of responses so the client // will know how many to expect. minipack_fwrite_array(output, message->message_count, &sz); check(sz > 0, "Unable to write multi message array"); // Start benchmark. struct timeval tv; gettimeofday(&tv, NULL); int64_t t0 = (tv.tv_sec*1000) + (tv.tv_usec/1000); // Loop over child messages and process. uint32_t i; for(i=0; i<message->message_count; i++) { rc = sky_server_process_message(server, true, input, output); check(rc == 0, "Unable to process child message"); // HACK: ZeroMQ is not releasing file handles soon enough so the sleep // is used to wait for some to close. This needs to be changed so that // all workers share the same ZeroMQ sockets. if(i % 1000 == 0) sleep(1); } // End benchmark. gettimeofday(&tv, NULL); int64_t t1 = (tv.tv_sec*1000) + (tv.tv_usec/1000); printf("[multi] t=%.3fs, i=%d\n", ((float)(t1-t0))/1000, i); // Close streams. fclose(input); fclose(output); sky_multi_message_free(message); return 0; error: sky_multi_message_free(message); fclose(input); fclose(output); return -1; }
// Retrieves a list of properties from the server for a table. This function is // synchronous and does not use a worker. // // server - The server. // header - The message header. // table - The table the message is working against // input - The input file stream. // output - The output file stream. // // Returns 0 if successful, otherwise returns -1. int sky_get_properties_message_process(sky_server *server, sky_message_header *header, sky_table *table, FILE *input, FILE *output) { int rc = 0; size_t sz; sky_get_properties_message *message = NULL; check(server != NULL, "Server required"); check(header != NULL, "Message header required"); check(table != NULL, "Table required"); check(input != NULL, "Input stream required"); check(output != NULL, "Output stream required"); struct tagbstring status_str = bsStatic("status"); struct tagbstring ok_str = bsStatic("ok"); struct tagbstring properties_str = bsStatic("properties"); // Parse message. message = sky_get_properties_message_create(); check_mem(message); rc = sky_get_properties_message_unpack(message, input); check(rc == 0, "Unable to parse 'get_properties' message"); // Return. // {status:"OK", properties:[{...}]} minipack_fwrite_map(output, 2, &sz); check(sz > 0, "Unable to write output"); check(sky_minipack_fwrite_bstring(output, &status_str) == 0, "Unable to write status key"); check(sky_minipack_fwrite_bstring(output, &ok_str) == 0, "Unable to write status value"); check(sky_minipack_fwrite_bstring(output, &properties_str) == 0, "Unable to write properties key"); // Loop over properties and serialize them. minipack_fwrite_array(output, table->property_file->property_count, &sz); check(sz > 0, "Unable to write properties array"); uint32_t i; for(i=0; i<table->property_file->property_count; i++) { sky_property *property = table->property_file->properties[i]; check(sky_property_pack(property, output) == 0, "Unable to write property"); } // Clean up. sky_get_properties_message_free(message); fclose(input); fclose(output); return 0; error: sky_get_properties_message_free(message); if(input) fclose(input); if(output) fclose(output); return -1; }
// Saves actions to file. // // action_file - The action file to save. // // Returns 0 if successful, otherwise returns -1. int sky_action_file_save(sky_action_file *action_file) { int rc; size_t sz; FILE *file = NULL; assert(action_file != NULL); check(action_file->path != NULL, "Action file path required"); // Open file. file = fopen(bdata(action_file->path), "w"); check(file, "Failed to open action file: %s", bdata(action_file->path)); // Write action count. rc = minipack_fwrite_array(file, action_file->action_count, &sz); check(rc == 0, "Unable to write actions array at byte: %ld", ftell(file)); // Write actions. uint32_t i; for(i=0; i<action_file->action_count; i++) { sky_action *action = action_file->actions[i]; // Write action id. minipack_fwrite_uint(file, action->id, &sz); check(sz != 0, "Unable to write action identifier at byte: %ld", ftell(file)); // Write action name. rc = sky_minipack_fwrite_bstring(file, action->name); check(rc == 0, "Unable to write action name at byte: %ld", ftell(file)); } // Close the file. fclose(file); return 0; error: if(file) fclose(file); return -1; }