Bulk HTTP request queue consumer Today I had to write a small tool to help me send HTTP requests in bulk. Rabbit was overloading my server, so I decided to change my consumers to buffer the contents of the request, before sending. After changing my API, I did this:

#include &lt;amqpcpp.h&gt;
#include &lt;amqpcpp/libev.h&gt;
#include &lt;ev.h&gt;
#include &lt;cpr/cpr.h&gt;

typedef std::unordered_map&lt;std::string, std::ostringstream&gt; HttpBuffer;
const char* RabbitQueue = getenv("RABBIT_NAME");
char QueueAddress[128];

int main()
{
    sprintf(QueueAddress, "amqp://%s:%s", getenv("RABBIT_HOST"), getenv("RABBIT_PORT"));

    int MaxThreads = std::thread::hardware_concurrency();
    std::vector&lt;std::thread&gt; threads;

    for (int i = 0; i &lt; MaxThreads; i++) {
        threads.push_back(std::thread(RabbitThread));
    }

    for (std::thread &amp;thread : threads) {
        thread.join();
    }

    threads.clear();
}

void RabbitThread()
{
    struct ev_loop *loop = ev_loop_new(0);
    AMQP::LibEvHandler handler(loop);
    AMQP::TcpConnection connection(&amp;handler, AMQP::Address(QueueAddress));
    AMQP::TcpChannel channel(&amp;connection);

    AMQP::MessageCallback onMessage = [&amp;channel](const AMQP::Message &amp;message, uint64_t deliveryTag, bool redelivered) {
        HttpBuffer[message.replyTo()] &lt;&lt; message.message().c_str() &lt;&lt; ",";
        if (HttpBuffer[message.replyTo()].tellp() &lt; 300000) {
            channel.ack(deliveryTag);
            return;
        }

        cpr::PostCallback(handle_response, cpr::Url{"http://localhost:8888"}, cpr::Body{HttpBuffer[message.replyTo()].str()});
        HttpBuffer[message.replyTo()].str("");

        channel.ack(deliveryTag);
    };

    channel.declareQueue(RabbitQueue);
    channel.bindQueue("default", RabbitQueue, "default");
    channel.consume(RabbitQueue).onReceived(onMessage);

    ev_run(loop);
    ev_loop_destroy(loop);
}


What do you guys think? How can I improve this one?
I don't know rabbit and have only small nit-picks regarding C++.

emplace

You might consider constructing threads in place instead of moving them to vector.

Instead of:

threads.push_back(std::thread(RabbitThread));


I would try:

threads.emplace_back(RabbitThread);


clear()

Is threads.clear(); in main() necessary?

struct and null pointer

This looks like C-style struct keyword usage. It is very rare to see in C++ (not saying it is wrong). 

struct ev_loop *loop = ev_loop_new(0);


This might be also ok and looks more familiar

ev_loop *loop = ev_loop_new(0);


One more thing and this is a wild guess. Is this zero really a NULL pointer?

struct ev_loop *loop = ev_loop_new(0);


This would be more C++11 way:

struct ev_loop *loop = ev_loop_new(nullptr);


hardware_concurrency()

I really have no idea where lies bottleneck in you use case but I suspect it is not CPU bound so maybe you might utilize even much more threads.

int MaxThreads = std::thread::hardware_concurrency();