static void process_the_patch (client_t *self, server_t *server) { char *inbox = fmq_config_resolve (self->config, "client/inbox", ".inbox"); char *filename = fmq_msg_filename (server->reply); // Filenames from server must start with slash, which we skip assert (*filename == '/'); filename++; if (fmq_msg_operation (server->reply) == FMQ_MSG_FILE_CREATE) { if (server->file == NULL) { server->file = fmq_file_new (inbox, filename); if (fmq_file_output (server->file)) { // File not writeable, skip patch fmq_file_destroy (&server->file); return; } } // Try to write, ignore errors in this version zframe_t *frame = fmq_msg_chunk (server->reply); fmq_chunk_t *chunk = fmq_chunk_new (zframe_data (frame), zframe_size (frame)); if (fmq_chunk_size (chunk) > 0) { fmq_file_write (server->file, chunk, fmq_msg_offset (server->reply)); server->credit -= fmq_chunk_size (chunk); } else { // Zero-sized chunk means end of file, so report back to caller zstr_sendm (self->pipe, "DELIVER"); zstr_sendm (self->pipe, filename); zstr_sendf (self->pipe, "%s/%s", inbox, filename); fmq_file_destroy (&server->file); } fmq_chunk_destroy (&chunk); } else if (fmq_msg_operation (server->reply) == FMQ_MSG_FILE_DELETE) { zclock_log ("I: delete %s/%s", inbox, filename); fmq_file_t *file = fmq_file_new (inbox, filename); fmq_file_remove (file); fmq_file_destroy (&file); } }
static void process_the_patch (client_t *self) { char *inbox = fmq_config_resolve (self->config, "client/inbox", ".inbox"); char *filename = fmq_msg_filename (self->reply); if (fmq_msg_operation (self->reply) == FMQ_MSG_FILE_CREATE) { if (self->file == NULL) { zclock_log ("I: create %s", filename); self->file = fmq_file_new (inbox, filename); if (fmq_file_output (self->file)) { // File not writeable, skip patch fmq_file_destroy (&self->file); return; } } // Try to write, ignore errors in this version zframe_t *frame = fmq_msg_chunk (self->reply); fmq_chunk_t *chunk = fmq_chunk_new (zframe_data (frame), zframe_size (frame)); if (fmq_chunk_size (chunk) > 0) { fmq_file_write (self->file, chunk, fmq_msg_offset (self->reply)); self->credit -= fmq_chunk_size (chunk); } else // Zero-sized chunk means end of file fmq_file_destroy (&self->file); fmq_chunk_destroy (&chunk); } else if (fmq_msg_operation (self->reply) == FMQ_MSG_FILE_DELETE) { zclock_log ("I: delete %s", filename); fmq_file_t *file = fmq_file_new (inbox, filename); fmq_file_remove (file); fmq_file_destroy (&file); } }
static void get_next_patch_for_client (server_t *self, client_t *client) { // Get next patch for client if we're not doing one already if (client->patch == NULL) client->patch = (fmq_patch_t *) zlist_pop (client->patches); if (client->patch == NULL) { client->next_event = finished_event; return; } // Get virtual filename from patch fmq_msg_set_filename (client->reply, fmq_patch_virtual (client->patch)); // We can process a delete patch right away if (fmq_patch_op (client->patch) == patch_delete) { fmq_msg_set_sequence (client->reply, client->sequence++); fmq_msg_set_operation (client->reply, FMQ_MSG_FILE_DELETE); client->next_event = send_delete_event; // No reliability in this version, assume patch delivered safely fmq_patch_destroy (&client->patch); } else if (fmq_patch_op (client->patch) == patch_create) { // Create patch refers to file, open that for input if needed if (client->file == NULL) { client->file = fmq_file_dup (fmq_patch_file (client->patch)); if (fmq_file_input (client->file)) { // File no longer available, skip it fmq_patch_destroy (&client->patch); fmq_file_destroy (&client->file); client->next_event = next_patch_event; return; } client->offset = 0; } // Get next chunk for file fmq_chunk_t *chunk = fmq_file_read (client->file, CHUNK_SIZE, client->offset); assert (chunk); // Check if we have the credit to send chunk if (fmq_chunk_size (chunk) <= client->credit) { fmq_msg_set_sequence (client->reply, client->sequence++); fmq_msg_set_operation (client->reply, FMQ_MSG_FILE_CREATE); fmq_msg_set_offset (client->reply, client->offset); fmq_msg_set_chunk (client->reply, zframe_new ( fmq_chunk_data (chunk), fmq_chunk_size (chunk))); client->offset += fmq_chunk_size (chunk); client->credit -= fmq_chunk_size (chunk); client->next_event = send_chunk_event; // Zero-sized chunk means end of file if (fmq_chunk_size (chunk) == 0) { fmq_file_destroy (&client->file); fmq_patch_destroy (&client->patch); } } else client->next_event = no_credit_event; fmq_chunk_destroy (&chunk); } }