示例#1
0
static void
sub_patch_add (sub_t *self, zdir_patch_t *patch)
{
    //  Skip file creation if client already has identical file
    zdir_patch_digest_set (patch);
    if (zdir_patch_op (patch) == patch_create) {
        char *digest = (char *) zhash_lookup (self->cache,
                                    zdir_patch_vpath (patch) + strlen(self->path) + 1);
        if (digest && streq (digest, zdir_patch_digest (patch)))
            return;             //  Just skip patch for this client
    }
    //  Remove any previous patches for the same file
    zdir_patch_t *existing = (zdir_patch_t *) zlist_first (self->client->patches);
    while (existing) {
        if (streq (zdir_patch_vpath (patch), zdir_patch_vpath (existing))) {
            zlist_remove (self->client->patches, existing);
            zdir_patch_destroy (&existing);
            break;
        }
        existing = (zdir_patch_t *) zlist_next (self->client->patches);
    }
    if (zdir_patch_op (patch) == patch_create)
        zhash_insert (self->cache,
            zdir_patch_digest (patch), zdir_patch_vpath (patch));
    //  Track that we've queued patch for client, so we don't do it twice
    zlist_append (self->client->patches, zdir_patch_dup (patch));
}
示例#2
0
static void
s_check_directory (s_agent_t *self)
{
    //  Get latest snapshot and build a patches list for any changes
    //  All patches are built using a virtual path starting at "/"
    zdir_t *dir = zdir_new (self->path, NULL);
    zlist_t *patches = zdir_diff (self->dir, dir, "/");

    //  Drop old directory and replace with latest version
    zdir_destroy (&self->dir);
    self->dir = dir;

    while (zlist_size (patches)) {
        zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches);
        if (zdir_patch_op (patch) == patch_create) {
            //  Shout new files to DROPS group
            //  Stupidest possible approach: send whole file as one frame
            //  Truncate file at arbitrary limit of 10MB
            zfile_t *file = zdir_patch_file (patch);
            if (zfile_input (file) == 0) {
                zchunk_t *chunk = zfile_read (file, 10 * 1024 * 1024, 0);
                assert (chunk);
                zmsg_t *msg = zmsg_new ();
                zmsg_addstr (msg, "CREATE");
                zmsg_addstr (msg, zdir_patch_vpath (patch));
                zmsg_add (msg, zframe_new (zchunk_data (chunk), zchunk_size (chunk)));
                zchunk_destroy (&chunk);
                zyre_shout (self->zyre, "DROPS", &msg);
            }
        }
        zdir_patch_destroy (&patch);
    }
    zlist_destroy (&patches);
}
示例#3
0
void
zdir_patch_test (bool verbose)
{
    printf (" * zdir_patch: ");

    //  @selftest
    zfile_t *file = zfile_new (".", "bilbo");
    assert (file);
    zdir_patch_t *patch = zdir_patch_new (".", file, patch_create, "/");
    assert (patch);
    zfile_destroy (&file);

    file = zdir_patch_file (patch);
    assert (file);
    assert (streq (zfile_filename (file, "."), "bilbo"));
    assert (streq (zdir_patch_vpath (patch), "/bilbo"));
    zdir_patch_destroy (&patch);

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif
    //  @end

    printf ("OK\n");
}
示例#4
0
文件: zdir_patch.c 项目: Talksum/czmq
//  --------------------------------------------------------------------------
//  Self test of this class
int
zdir_patch_test (bool verbose)
{
    printf (" * zdir_patch: ");

    //  @selftest
    zfile_t *file = zfile_new (".", "bilbo");
    zdir_patch_t *patch = zdir_patch_new (".", file, patch_create, "/");
    zfile_destroy (&file);
    
    file = zdir_patch_file (patch);
    assert (streq (zfile_filename (file, "."), "bilbo"));
    assert (streq (zdir_patch_vpath (patch), "/bilbo"));
    zdir_patch_destroy (&patch);
    //  @end

    printf ("OK\n");
    return 0;
}
示例#5
0
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 = (zdir_patch_t *) zlist_pop (client->patches);           
    if (client->patch == NULL) {                                                
        client->next_event = finished_event;                                    
        return;                                                                 
    }                                                                           
    //  Get virtual path from patch                                             
    fmq_msg_set_filename (client->reply, zdir_patch_vpath (client->patch));     
                                                                                
    //  We can process a delete patch right away                                
    if (zdir_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       
        zdir_patch_destroy (&client->patch);                                    
    }                                                                           
    else                                                                        
    if (zdir_patch_op (client->patch) == patch_create) {                        
        //  Create patch refers to file, open that for input if needed          
        if (client->file == NULL) {                                             
            client->file = zfile_dup (zdir_patch_file (client->patch));         
            if (zfile_input (client->file)) {                                   
                //  File no longer available, skip it                           
                zdir_patch_destroy (&client->patch);                            
                zfile_destroy (&client->file);                                  
                client->next_event = next_patch_event;                          
                return;                                                         
            }                                                                   
            client->offset = 0;                                                 
        }                                                                       
        //  Get next chunk for file                                             
        zchunk_t *chunk = zfile_read (client->file, CHUNK_SIZE, client->offset);
        assert (chunk);                                                         
                                                                                
        //  Check if we have the credit to send chunk                           
        if (zchunk_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 (                      
                zchunk_data (chunk),                                            
                zchunk_size (chunk)));                                          
                                                                                
            client->offset += zchunk_size (chunk);                              
            client->credit -= zchunk_size (chunk);                              
            client->next_event = send_chunk_event;                              
                                                                                
            //  Zero-sized chunk means end of file                              
            if (zchunk_size (chunk) == 0) {                                     
                zfile_destroy (&client->file);                                  
                zdir_patch_destroy (&client->patch);                            
            }                                                                   
        }                                                                       
        else                                                                    
            client->next_event = no_credit_event;                               
                                                                                
        zchunk_destroy (&chunk);                                                
    }                                                                           
}
示例#6
0
///
//  Return patch virtual file path
const QString QZdirPatch::vpath ()
{
    const QString rv = QString (zdir_patch_vpath (self));
    return rv;
}