Esempio n. 1
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 = (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);                                                   
    }                                                                                 
}
Esempio n. 2
0
void
fmq_msg_test (bool verbose)
{
    printf (" * fmq_msg:");

    if (verbose)
        printf ("\n");

    //  @selftest
    //  Simple create/destroy test
    fmq_msg_t *self = fmq_msg_new ();
    assert (self);
    fmq_msg_destroy (&self);
    //  Create pair of sockets we can send through
    //  We must bind before connect if we wish to remain compatible with ZeroMQ < v4
    zsock_t *output = zsock_new (ZMQ_DEALER);
    assert (output);
    int rc = zsock_bind (output, "inproc://selftest-fmq_msg");
    assert (rc == 0);

    zsock_t *input = zsock_new (ZMQ_ROUTER);
    assert (input);
    rc = zsock_connect (input, "inproc://selftest-fmq_msg");
    assert (rc == 0);


    //  Encode/send/decode and verify each message type
    int instance;
    self = fmq_msg_new ();
    fmq_msg_set_id (self, FMQ_MSG_OHAI);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_OHAI_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ);

    fmq_msg_set_path (self, "Life is short but Now lasts for ever");
    zhash_t *icanhaz_options = zhash_new ();
    zhash_insert (icanhaz_options, "Name", "Brutus");
    fmq_msg_set_options (self, &icanhaz_options);
    zhash_t *icanhaz_cache = zhash_new ();
    zhash_insert (icanhaz_cache, "Name", "Brutus");
    fmq_msg_set_cache (self, &icanhaz_cache);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_path (self), "Life is short but Now lasts for ever"));
        zhash_t *options = fmq_msg_get_options (self);
        assert (zhash_size (options) == 2);
        assert (streq ((char *) zhash_first (options), "Brutus"));
        assert (streq ((char *) zhash_cursor (options), "Name"));
        zhash_destroy (&options);
        if (instance == 1)
            zhash_destroy (&icanhaz_options);
        zhash_t *cache = fmq_msg_get_cache (self);
        assert (zhash_size (cache) == 2);
        assert (streq ((char *) zhash_first (cache), "Brutus"));
        assert (streq ((char *) zhash_cursor (cache), "Name"));
        zhash_destroy (&cache);
        if (instance == 1)
            zhash_destroy (&icanhaz_cache);
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_NOM);

    fmq_msg_set_credit (self, 123);
    fmq_msg_set_sequence (self, 123);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_credit (self) == 123);
        assert (fmq_msg_sequence (self) == 123);
    }
    fmq_msg_set_id (self, FMQ_MSG_CHEEZBURGER);

    fmq_msg_set_sequence (self, 123);
    fmq_msg_set_operation (self, 123);
    fmq_msg_set_filename (self, "Life is short but Now lasts for ever");
    fmq_msg_set_offset (self, 123);
    fmq_msg_set_eof (self, 123);
    zhash_t *cheezburger_headers = zhash_new ();
    zhash_insert (cheezburger_headers, "Name", "Brutus");
    fmq_msg_set_headers (self, &cheezburger_headers);
    zchunk_t *cheezburger_chunk = zchunk_new ("Captcha Diem", 12);
    fmq_msg_set_chunk (self, &cheezburger_chunk);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_sequence (self) == 123);
        assert (fmq_msg_operation (self) == 123);
        assert (streq (fmq_msg_filename (self), "Life is short but Now lasts for ever"));
        assert (fmq_msg_offset (self) == 123);
        assert (fmq_msg_eof (self) == 123);
        zhash_t *headers = fmq_msg_get_headers (self);
        assert (zhash_size (headers) == 2);
        assert (streq ((char *) zhash_first (headers), "Brutus"));
        assert (streq ((char *) zhash_cursor (headers), "Name"));
        zhash_destroy (&headers);
        if (instance == 1)
            zhash_destroy (&cheezburger_headers);
        assert (memcmp (zchunk_data (fmq_msg_chunk (self)), "Captcha Diem", 12) == 0);
        if (instance == 1)
            zchunk_destroy (&cheezburger_chunk);
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_KTHXBAI);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_SRSLY);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }
    fmq_msg_set_id (self, FMQ_MSG_RTFM);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }

    fmq_msg_destroy (&self);
    zsock_destroy (&input);
    zsock_destroy (&output);
    //  @end

    printf ("OK\n");
}