3

I have developed a client server application with casablanca cpprestskd. Every 5 minutes a client send informations from his task manager (processes,cpu usage etc) to server via POST method.

The project should be able to manage about 100 clients. Every time that server receives a POST request he opens an output file stream ("uploaded.txt") ,extract some initial infos from client (login,password),manage this infos, save all infos in a file with the same name of client (for example: client1.txt, client2.txt) in append mode and finally reply to client with a status code. This is basically my POST handle code from server side:

void Server::handle_post(http_request request)
{

auto fileBuffer = 
     std::make_shared<Concurrency::streams::basic_ostream<uint8_t>>();
try
{
    auto stream = concurrency::streams::fstream::open_ostream(
        U("uploaded.txt"),
        std::ios_base::out | std::ios_base::binary).then([request, fileBuffer](pplx::task<Concurrency::streams::basic_ostream<unsigned char>> Previous_task)
    {

        *fileBuffer = Previous_task.get();
        try
        {
            request.body().read_to_end(fileBuffer->streambuf()).get();
        }
        catch (const exception&)
        {
            wcout << L"<exception>" << std::endl;
            //return pplx::task_from_result();
        }
        //Previous_task.get().close();

    }).then([=](pplx::task<void> Previous_task)
    {


        fileBuffer->close();
        //Previous_task.get();
    }).then([](task<void> previousTask)
    {
        // This continuation is run because it is value-based.
        try
        {
            // The call to task::get rethrows the exception.

            previousTask.get();
        }
        catch (const exception& e)
        {
            wcout << e.what() << endl;
        }
    });
    //stream.get().close();
}
catch (const exception& e)
{
    wcout << e.what() << endl;
}


ManageClient();

request.reply(status_codes::OK, U("Hello, World!")).then([](pplx::task<void> t) { handle_error(t); });
return;

}

Basically it works but if i try to send info from due clients at the same time sometimes it works sometimes it doen't work. Obviously the problem if when i open "uploaded.txt" stream file. Questions:

1)Is CASABLANCA http_listener real multitasking?how many task it's able to handle? 2)I didn't found in documentation ax example similar to mine,the only one who is approaching to mine is "Casalence120" Project but he uses Concurrency::Reader_writer_lock class (it seems a mutex method). What can i do in order to manage multiple POST? 3)Is it possible to read some client infos before starting to open uploaded.txt? I could open an output file stream directly with the name of the client. 4)If i lock access via mutex on uploaded.txt file, Server become sequential and i think this is not a good way to use cpprestsdk. I'm still approaching cpprestskd so any suggestions would be helpful.

kenhero
  • 95
  • 2
  • 11

1 Answers1

3
  1. Yes, the REST sdk processes every request on a different thread
  2. I confirm there are not many examples using the listener. The official sample using the listener can be found here: https://github.com/Microsoft/cpprestsdk/blob/master/Release/samples/CasaLens/casalens.cpp
  3. I see you are working with VS. I would strongly suggest to move to VC++2015 or better VC++2017 because the most recent compiler supports co-routines. Using co_await dramatically simplify the readability of the code. Substantially every time you 'co_await' a function, the compiler will refactor the code in a "continuation" avoiding the penalty to freeze the threads executing the function itself. This way, you get rid of the ".then" statements.
  4. The file problem is a different story than the REST sdk. Accessing the file system concurrently is something that you should test in a separate project. You can probably cache the first read and share the content with the other threads instead of accessing the disk every time.
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
raf
  • 131
  • 1
  • 4
  • I don't need to share info with other clients when i open "uploaded.txt" stream file,it's just a temporary file that i need to read client login and password and after some stuff i need to copy it in a file with the same name of client. Is there a chance to open a stream file with a different name every time?I could solve in that way! – kenhero May 08 '17 at 10:40
  • I am confused by your last request. There is of course the chance to open the stream file with a different name, it is just up to you understanding the flow of the async calls. Probably the code would simplify by using coroutines. The continuations using "then" can be difficult to understand when debugging. (Did I understand the question?) – raf Jun 07 '17 at 16:02
  • 1
    I solved open a stream file with different names for every client. I stressed the test with Jmeter and Server is able to manage multiple client requests. Now i have to finish test with functional unit test ,after that i will try to change .then method with coroutines. Thanks – kenhero Jun 08 '17 at 10:44