Giter Site home page Giter Site logo

Comments (4)

tt4g avatar tt4g commented on June 7, 2024

You forgot to call function pqxx::connection::get_notifs() to receive notifications.

  • /**
    * @name Notifications and Receivers
    */
    //@{
    /// Check for pending notifications and take appropriate action.
    /** This does not block. To wait for incoming notifications, either call
    * await_notification() (it calls this function); or wait for incoming data
    * on the connection's socket (i.e. wait to read), and then call this
    * function repeatedly until it returns zero. After that, there are no more
    * pending notifications so you may want to wait again.
    *
    * If any notifications are pending when you call this function, it
    * processes them by finding any receivers that match the notification string
    * and invoking those. If no receivers match, there is nothing to invoke but
    * we do consider the notification processed.
    *
    * If any of the client-registered receivers throws an exception, the
    * function will report it using the connection's errorhandlers. It does not
    * re-throw the exceptions.
    *
    * @return Number of notifications processed.
    */
    int get_notifs();
  • libpqxx/src/connection.cxx

    Lines 560 to 611 in 2ffb711

    int pqxx::connection::get_notifs()
    {
    if (not consume_input())
    throw broken_connection{"Connection lost."};
    // Even if somehow we receive notifications during our transaction, don't
    // deliver them.
    if (m_trans)
    PQXX_UNLIKELY
    return 0;
    int notifs = 0;
    for (auto N{get_notif(m_conn)}; N.get(); N = get_notif(m_conn))
    {
    notifs++;
    auto const Hit{m_receivers.equal_range(std::string{N->relname})};
    if (Hit.second != Hit.first)
    {
    std::string const payload{N->extra};
    for (auto i{Hit.first}; i != Hit.second; ++i) try
    {
    (*i->second)(payload, N->be_pid);
    }
    catch (std::exception const &e)
    {
    try
    {
    process_notice(internal::concat(
    "Exception in notification receiver '", i->first,
    "': ", e.what(), "\n"));
    }
    catch (std::bad_alloc const &)
    {
    // Out of memory. Try to get the message out in a more robust way.
    process_notice(
    "Exception in notification receiver, "
    "and also ran out of memory\n");
    }
    catch (std::exception const &)
    {
    process_notice(
    "Exception in notification receiver "
    "(compounded by other error)\n");
    }
    }
    }
    N.reset();
    }
    return notifs;
    }

Note

There is also a convenience function pqxx::connection::await_notification() that waits for N seconds until notified.

  • /// Wait for a notification to come in.
    /** There are other events that will also terminate the wait, such as the
    * backend failing. It will also wake up periodically.
    *
    * If a notification comes in, the call will process it, along with any other
    * notifications that may have been pending.
    *
    * To wait for notifications into your own event loop instead, wait until
    * there is incoming data on the connection's socket to be read, then call
    * @ref get_notifs() repeatedly until it returns zero.
    *
    * @return Number of notifications processed.
    */
    int await_notification();
    /// Wait for a notification to come in, or for given timeout to pass.
    /** There are other events that will also terminate the wait, such as the
    * backend failing, or timeout expiring.
    *
    * If a notification comes in, the call will process it, along with any other
    * notifications that may have been pending.
    *
    * To wait for notifications into your own event loop instead, wait until
    * there is incoming data on the connection's socket to be read, then call
    * @ref get_notifs repeatedly until it returns zero.
    *
    * @return Number of notifications processed
    */
    int await_notification(std::time_t seconds, long microseconds);
  • libpqxx/src/connection.cxx

    Lines 1041 to 1068 in 2ffb711

    int pqxx::connection::await_notification()
    {
    int notifs = get_notifs();
    if (notifs == 0)
    {
    PQXX_LIKELY
    internal::wait_fd(socket_of(m_conn), true, false, 10, 0);
    notifs = get_notifs();
    }
    return notifs;
    }
    int pqxx::connection::await_notification(
    std::time_t seconds, long microseconds)
    {
    int const notifs = get_notifs();
    if (notifs == 0)
    {
    PQXX_LIKELY
    internal::wait_fd(
    socket_of(m_conn), true, false,
    check_cast<unsigned>(seconds, "Seconds out of range."),
    check_cast<unsigned>(microseconds, "Microseconds out of range."));
    return get_notifs();
    }
    return notifs;
    }

from libpqxx.

afpgit avatar afpgit commented on June 7, 2024

I replaced

while(true){
    waitForChannel(L1);
    waitForChannel(L2);
}

with

while (true) {
    conn.await_notification();
}

and things started to work. Thank you. I get the correct messages:

Received notification: channel1 pid=128
Received notification: channel2 pid=43
Received notification: channel1 pid=43
Received notification: channel1 pid=43
Received notification: channel1 pid=43
Received notification: channel2 pid=43
Received notification: channel2 pid=43
...

My question is how I can tell which channel was triggered? I would like to be able to take proper action based on whether the trigger came from channel1 or channel2.

from libpqxx.

tt4g avatar tt4g commented on June 7, 2024

The TestListener is the object corresponding to each channel.
L1 receives notifications for channel1 and L2 for channel2.
Or you can use pqxx::notification_receiver::channel() to get the channel name.

from libpqxx.

tt4g avatar tt4g commented on June 7, 2024

@afpgit If the problem has been resolved, close this issue.

from libpqxx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.