2

I'm relatively new to boost-asio and I'm wondering if it's possible to make it work with KDB+ api here.

I tried something like the below but it doesn't seem to work properly,

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#define KXVER 3

#include "kx/k.h"

using boost::asio::ip::tcp;
namespace posix = boost::asio::posix;

class Feedhandler
{
public:
    Feedhandler(boost::asio::io_service &io_service) : m_qsvc(io_service) {

        char host[] = "localhost";
        int port = 6812;

        m_fd = khpu(host, port, "user:pass");
        m_qsvc.assign(m_fd);

        start_operations();

        K ret = k(m_fd, ".u.sub", ks(""), ks(""), (K)0);

    }

    void start_operations()
    {
        boost::asio::async_read(m_qsvc, boost::asio::null_buffers(),
                                boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));

    }

    void handle_read(const boost::system::error_code& error, size_t size)
    {
        K data = k(m_fd,(S)0);
        start_operations();
    }


private:
    int m_fd;
    posix::stream_descriptor m_qsvc;

};

int main(int argc, char* argv[])
{

    boost::asio::io_service io_service;

    Feedhandler fh(io_service);

    io_service.run();

    return 0;
}

The handle_read method gets hit once and then subsequently there's no more call-backs.

Danny
  • 391
  • 2
  • 12
  • what do you mean by no more call-backs? did you mean that the read handlers are not invoked? It usually be invoked when the FD is ready to read, are you sure the FD is ready to read, but the handler isn't executing? In-case of assigning FD and starting io_context's event-loop...I see no flaw. – RaGa__M Jul 22 '19 at 07:37
  • looked into your api (never heard of KDB), it looks like ` k(m_fd, ".u.sub", ks(""), ks(""), (K)0);` function is what used to send message...and in the above code, it looks there is only one call in the `Feedhandler`'s constructor, you sure there is a write been happening to `m_fd`? – RaGa__M Jul 22 '19 at 07:39
  • In a gist: I see only one write to `m_fd`. – RaGa__M Jul 22 '19 at 07:56
  • I mean that handle_read is only called once, and there is valid data in that call, but subsequently no other calls. The KDB api is such that k(m_fd, ".u.sub", ks(""), ks(""), (K)0) is a subscribe call, and it only needs to get called once. After the subscribe call, we only need to check that the file descriptor is reading for reading, and call data = k(m_fd,(S)0) repeatedly, which will return the published data. – Danny Jul 22 '19 at 11:47
  • who is writing to that FD? how do you sure that the write is happening? – RaGa__M Jul 22 '19 at 12:00
  • Does this call ` k(m_fd,(S)0);` block? layout its specifics like how much does it read, when will it return.. – RaGa__M Jul 22 '19 at 12:01
  • The details are in the link https://code.kx.com/v2/interfaces/c-client-for-q/#connecting-to-a-q-server. Some where one page down, the code just repeatedly loops and wait for fd to be readable, then calls the k(fd, ..) method. – Danny Jul 22 '19 at 12:05
  • That's the only thing we know about the API, the rest is not exposed by the KDB library. – Danny Jul 22 '19 at 12:07
  • strangely, when i tried on linux it works without issue, but when i first posted the issue, i was using macos on my home machine, which didn't work. – Danny Jul 22 '19 at 17:24
  • @Explorer_N i appreciate your help with issue, do you know if there's a differencet between osx and linux for the behavior to be different? – Danny Jul 23 '19 at 10:10
  • asio use different reactor for different OS platform, in-case of Linux: asio will pick `epoll-rector`, in-case of __APPLE__ / *bsd: asio will pick `kqueue_reactor`. – RaGa__M Jul 23 '19 at 11:42
  • I've not spent much time on your question since you said "strangely, when i tried on linux it works" ... – RaGa__M Jul 23 '19 at 11:43

1 Answers1

0

Actually, it's better to use async_wait instead of async_read, like below,

m_qsvc.async_wait(boost::asio::posix::stream_descriptor::wait_read, 
   boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error) );
Danny
  • 391
  • 2
  • 12