Giter VIP home page Giter VIP logo

Comments (13)

rodgert avatar rodgert commented on August 15, 2024

My off the cuff response would be probably not, at least as the library
is currently constituted. I've attempted to replicate some CZMQ
functionality along the way but wrapping CZMQ directly wasn't something I
seriously considered. I don't remember whether CZMQ exposes polling on
individual sockets or handles it for the caller. Integrating with Asio
requires some access to the polling machinery (which is why AZMQ doesn't
use libzmq's convenience polling routines).

On Tuesday, May 10, 2016, Matt Schuckmann [email protected] wrote:

I'd really like to be able to use this library to get all of the great
features of ASIO with another ZMQ library Zyre. The problem is Zyre uses
czmq to create and manage ZMQ sockets.
Is there a way to attach a azmq socket object to an already created ZMQ
socket?
Or is there a pattern that you can suggest on how to accomplish mixing
these 2 libraries?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#122

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

So got something close working but it's not what I really want.
I create an azmq::actor and in the background thread create and manage the Zyre context. I use the azmq::actor's pipe to pass messages/operations, etc back and forth from the client side to the background thread.
The problem is I can't pend on events from both the azmq::actor backend side of the pipe and the Zyre CZMQ socket, I have to poll on one and then the other with a short timeout for each which is not ideal.

I tried passing the return value from azmq::socket::native_handle() to a CZMQ zpoller and it seemed to notify when something was sent over the azmq::actor pipe but I couldn't figure out how to receive the actual message.

Alternatively it looks like you can get the libzmq socket from the Zyre node like so:

zyre_t *node = zyre_new("foo");
zsock_t* sock = zyre_socket(node);
void* zmq_sock = zsock_resolve(sock);

But I don't see anyway to bind the libzmq socket to a azmq::socket so that I can asynchronously receive on it ASIO style. It looks like it "might" be possible to create a constructor for azmq::socket that takes an already constructed libzmq socket but I really haven't dug into it yet.

from azmq.

rodgert avatar rodgert commented on August 15, 2024

������Currently construction is handled by delegating through to
detail::socket_service::per_descriptor_data::do_open(). It would be simple
enough to add another method that takes a zmq_sock* and does the rest of
the required setup of the per_descriptor_data instance.

��A constructor that accepts a zmq_sock* might work, but I think (having
given only about 5 minutes of consideration, so happy to be convinced
otherwise) I'd argue for a free function perhaps -

socket make_socket(io_service&, zmq_sock*) { ... }

I'd have said call it attach, but that concept is already claimed for
another purpose in the library.

One other complication is lifetime of zmq_sock_, currently socket is
assumed to own the underlying zmq_sock_. Would you also need a detach()
method that simply abandons the zmq_sock* hoping for CZMQ to clean it up
separately?

On Tue, May 17, 2016 at 12:22 PM, Matt Schuckmann [email protected]
wrote:

So got something close working but it's not what I really want.
I create an azmq::actor and in the background thread create and manage the
Zyre context. I use the azmq::actor's pipe to pass messages/operations, etc
back and forth from the client side to the background thread.
The problem is I can't pend on events from both the azmq::actor backend
side of the pipe and the Zyre CZMQ socket, I have to poll on one and then
the other with a short timeout for each which is not ideal.

I tried passing the return value from azmq::socket::native_handle() to a
CZMQ zpoller and it seemed to notify when something was sent over the
azmq::actor pipe but I couldn't figure out how to receive the actual
message.

Alternatively it looks like you can get the libzmq socket from the Zyre
node like so:

zyre_t node = zyre_new("foo");
zsock_t
sock = zyre_socket(node);
void* zmq_sock = zsock_resolve(sock);

But I don't see anyway to bind the libzmq socket to a azmq::socket so that
I can asynchronously receive on it ASIO style. It looks like it "might" be
possible to create a constructor for azmq::socket that takes an already
constructed libzmq socket but I really haven't dug into it yet.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#122 (comment)

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

Thank you for the input.
I'm happy to take your suggestion of a free function and see where it leads.

As for lifetime, yes the easiest thing to do in the short term would be to have a detach() and hope that the user of the library is smart enough to make the right calls to CZMQ or libzmq to clean up. It's definitely not the best solution but barring an equivalent detach mechanism on the CZMQ side there probably isn't a good solution.

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

@rodgert I've done a quick implementation mostly following your suggestions and it's working great.
Right now I've done it by creating a new azmq::socket constructor and a release() method:

    explicit socket(boost::asio::io_service& ios,
                    void* handle,
                    bool optimize_single_threaded = false)
            : azmq::detail::basic_io_object<detail::socket_service>(ios) {
        boost::system::error_code ec;
        if (get_service().do_open(implementation, handle, optimize_single_threaded, ec))
            throw boost::system::system_error(ec);
    }

    void release() {
        //the service release calls release on the socket_type unique_ptr. 
        get_service().release(implementation);
    }

I looked into creating a make_socket() free function like you suggested but I must be missing something, I think you'd have to create normal azmq::socket() of some type and then destroy it replacing it with the specified libzmq socket and that just seems inefficient and silly. What am I missing?

Also I have mixed feelings about the release() method, I worry about someone calling release() on a azmq::socket that was constructed the standard way, in which case there would be no way to clean up the socket and it would leak. It seems like it would be better to specify if the azmq::socket should clean up the libzmq socket when the azmq::socket is created via a flag or maybe a free functor passed to the constructor.

from azmq.

rodgert avatar rodgert commented on August 15, 2024

WRT 'release()' It is certainly possible that somebody could use it that way. That is why it is important to modify the per-descriptor data to tear down any associated state that is outside of libzmq. Then, if the socket is destroyed later by calling zmq_close() there will be no issue.

I'll try and take a stab at this over the weekend, pretty sure it is possible to make this a free function.

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

OK I look forward to seeing what you come up with and I really appreciate you taking the time to look into this.
FYI the changes I've made so far are in my fork of the library at: mschuckmann@a9b4e58

from azmq.

rodgert avatar rodgert commented on August 15, 2024

Update on this, I have an implementation that supports construction of an azmq::socket from a 'native' zmq socket pointer as a free function with a ::release() method on the socket to cancel all outstanding async ops, teardown the associated infrastructure and release ownership of the underlying 'native' zmq socket pointer to the caller. This also fixes an issue that @oliora identified in #77, specifically the dtor for socket does not cancel outstanding async ops.

I need to put some unit tests around this before committing, most likely by the weekend.

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

Very cool, I look forward to seeing it, and thank you.

from azmq.

rodgert avatar rodgert commented on August 15, 2024

I've added the following free function -

socket_from_zmq_sock()

Which takes an Asio io_service and a valid zeromq socket void* and returns an azmq::socket

There is also now a azmq::socket::release() method that will terminate any outstanding async IO operations initiated through the socket interface and return the underlying zeromq socket void*

Note, the only valid operation at this point on the azmq::socket is destruction.

This has only been lightly tested, patches welcome. If there's some bike shedding around the free function name, that's probably ok too.

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

OK I see what you have done, instead of a public constructor that takes the raw ZMQ socket you created a private constructor that creates an uninitialized azmq::socket and the friend function socket_from_zmq_sock() that creates an uninitialized socket and then initializes it with the raw ZMQ socket.

I'm not sure I see the benefit to doing one way or the other but I won't argue with something that works and is tested, thank you.

from azmq.

rodgert avatar rodgert commented on August 15, 2024

I was thinking along the lines of make_shared.

Not sure if you've seen the commentary about the issue with releasing the
zmq socket pointer (doesn't and mostly can't work on Windows).

On Tuesday, May 31, 2016, Matt Schuckmann [email protected] wrote:

OK I see what you have done, instead of a public constructor that takes
the raw ZMQ socket you created a private constructor that creates an
uninitialized azmq::socket and the friend function socket_from_zmq_sock()
that creates an uninitialized socket and then initializes it with the raw
ZMQ socket.

I'm not sure I see the benefit to doing one way or the other but I won't
argue with something that works and is tested, thank you.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#122 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAHYB12QDDViuIMroT95RBZnBcI4dQpvks5qHN4FgaJpZM4IbW4C
.

from azmq.

mschuckmann avatar mschuckmann commented on August 15, 2024

I had seen the commentary about windows but didn't really look into it until now, mostly I'm focused on Linux but having a cross platform solution is important for the library.
I proposed a solution but I'm not sure if it really helps as I'm still a little confused about where the problem is.

from azmq.

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.