0

I'm currently looking for a good solution for the following use-case in C++ (preferably C++11 or C++14):

The program is running a server with a TCP connection. Other clients can connect at any time to this server and trigger a calculation (which takes a few seconds). There should only run one calculation at a time. Other calculation calls should be queued and their call blocked until the result is ready. If the current calculation fails, all other calculations shouldn't be carried out and returned immediately.

Here is some example code describing the steps:

// the first client calling this function should get the token,
// all others have to wait until first one finished.
// Then the next in the queue can continue
bool gotCalculateRequest() {

    // blocks until currently running calulation finished.
    // If getToken returns false, do not queue this request for calculation
    if (!getToken()) {
        // notify client that calculation was aborted
        return false;
    }

    // now we have the token and we can start calculation

    if (!doStuff()) {
        // give back the token and abort other requests in the queue
        freeTokenAndAbortOthers();
        return false;
    }

    // give back the token. This should automatically notify the next waiting request to continue
    freeToken();
    return true;
}

I thought about using std::promise and std::future for that: When a request comes in the future is added to a queue and the call waits on the future. When the previous calculation finishes it uses the promise to notify the next caller. Can you think about a better solution?

2
  • Just to clarify, if client A asks for a calculation that fails, then a queued calculation for client B should also fail?
    – Phil Lello
    Feb 25, 2016 at 13:18
  • Yes, correct. The calculation for client B should not be executed then and just return with fail. Feb 25, 2016 at 16:26

1 Answer 1

1

Instead of the extra token and such, I'd handle things on the back end. In other words, when a request comes in, always just push it into the queue.

The back end (the part that pulls requests from the queue) just pulls items, and carries out calculations. When/if a failure occurs, it just sets a failed flag, and from then on, it returns false (or whatever it needs to do to signal failure).

bool do_calculation(calc_spec const &input, result_type &output) { 
    static bool failed;

    if (failed)
       return false;

    output = calculation_impl(input);
    if (calc_failed(output)) {
         failed = true;
         return false;
    }

    return true;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.