使用rxcpp进行调度和超时处理

时间:2015-09-23 12:00:01

标签: c++ reactive-programming rxcpp

我是新手使用rxcpp并尝试在以下场景中一起实现功能:

我有一个数据源可以从一个单独的源检索命令,我写的代码会将这些命令检索到rxcpp observable中。它具有特殊条件,即如果在一定时间内没有收到命令,则将运行订阅者onError函数而不是onNext,但超时只能在接收第一个命令之前发生。收到第一个命令后,无论多长时间接收任何其他命令,都不会发生超时。

我试图通过以下方式实现这一目标:

auto timeout = rxcpp::observable<>::timer(std::chrono::steady_clock::now() + timeout,
                             rxcpp::observe_on_event_loop()).map([](int val) // Note, converts the value type of the timer observable and converts timeouts to errors
{
    std::cout << "TIMED OUT!" << std::endl;
    throw std::runtime_error("timeout");
    return command_type();
});
auto commands = timeout.amb(rxcpp::observe_on_event_loop(), createCommandSource(event_loop_scheduler, ...));

我遇到的问题是超时发生在收到任何命令之前,即使它们在超时发生之前插入了很多。我已经尝试了从1000毫秒到5000毫秒的时间,它没有任何区别。如果我删除超时代码,则立即收到命令。我怀疑我可能只是误解了如何在rxcpp中使用调度程序,所以我想知道如何实现这一点。

2 个答案:

答案 0 :(得分:2)

我写了一个简单的createCommandSource。这对我有用:

#include "rxcpp/rx.hpp"
using namespace rxcpp;
using namespace rxcpp::sources;
using namespace rxcpp::util;

using namespace std;

struct command_type {};

int main()
{
    auto eventloop = rxcpp::observe_on_event_loop();
    auto createCommandSource = [=]() {
        return rxcpp::observable<>::interval(std::chrono::seconds(1), eventloop).map([](long) {return command_type(); });
    };
    auto timeout = rxcpp::observable<>::timer(eventloop.now() + std::chrono::seconds(2), eventloop).map([](long ) // Note, converts the value type of the timer observable and converts timeouts to errors
    {
        std::cout << "TIMED OUT!" << std::endl;
        throw std::runtime_error("timeout");
        return command_type();
    });
    auto commands = timeout.amb(eventloop, createCommandSource().take(5));

    commands
        .as_blocking().subscribe(
        [](command_type) {printf("command\n"); },
        [](std::exception_ptr) {printf("execption\n"); });

    std::this_thread::sleep_for(std::chrono::seconds(2));

    return 0;
}

答案 1 :(得分:0)

现在,您可以使用.timeout()运算符来管理超时,该运算符将间隔持续时间作为这样的参数提供:

createCommandSource(event_loop_scheduler, ...).timeout((std::chrono::seconds(2));

据我了解,此运算符可确保在流创建与第一个命令之间,任意一对命令之间以及在最后一个命令与命令流的on_complete()事件之间保持超时。