Just wanted to add that the enum approach makes more sense anyway,
since the zmq context creates the sockets. Clients should not
instantiate socket types explicitly. Typical builder pattern.
I also think that the term 'context' becomes a misnomer in the Java
driver. I would rather have a the 'Zmq' class with an internal
context. More like the second approach thus.
In principal:
class ZmqContext {
//internal pointer to c context
private final long contextPtr;
public ZmqContext {
contextPtr = zmq_init(...);
}
public long getCPointer() {
return contextPtr;
}
}
class Zmq {
private final ZmqContext zc;
public Zmq() {
lazyLoadLib('zmq');
zc = new ZmqContext();
}
public ISocket createSocket(enum sockType) {
return new MultiSocket(zc, sockType);
}
}
interface ISocket {
public IResult send();
//etc
}
package private class MultiSocket implements ISocket {
private enum sockType;
public MultiSocket(ZmqContext context, SockType sockType) {
this.socketHandle = zmq_create_socket(context.getCPointer,
sockType.C_VALUE);
}
public IResult send(data) {
return new MultiResult(zmq_send(data, ....));
}
}
etc...
The client would then only have to do:
Zmq zmq = new Zmq();
ISocket sock = zmq.createSocket(SocketType.XX);
sock.send(data);
The context passing becomes transparent. You have one Zmq instance per
application (I assumed that you can have multiple zmq intances per JVM
/ executable).
The 'class per socket type' is only useful if you want to add
type-specific code in the language wrapper, which I don't think should
be needed in most cases.
Just my 2 cents.
Alexander T
On 2/26/10, Martin Sustrik <[email protected]> wrote:
> Brian Granger wrote:
>
>> * For an OO language, it is awkward to instantiate a Socket by hand
>> when you have to pass the Context:
>>
>> s = Socket(ctx, zmq.REP)
>>
>> A better approach would be to let the context create the Socket:
>>
>> ctx.create_socket(zmq.REP)
>>
>> That way, you are sure to get the ctx argument correct. This is
>> implemented in the
>> Python binding.
>
> Sure, why not.
>
>> * It is tempting to make the different socket types subclasses:
>>
>> SocketBase
>> RepSocket
>> ReqSocket
>> P2PSocket
>>
>> Rather than using the zmq.REP|REQ... flags. I did not implement this
>> as it seemed to
>> go too afar from the C/C++ bindings.
>
> I would strongly suggest not to go this way.
>
> Socket types & socket options are deliberately designed as 0MQ extension
> points, meaning that while ABI stays stable, new functionality can be
> added via new socket types/options.
>
> Therefore, there should be no socket-type- or option- specific code in
> the bindings. That way new functionality can be accessed without a
> change to the API (put aside adding new constants).
>
> Have a look how BSD socket API is designed. I believe they've got this
> thing exactly right and that's one of the main reasons why BSD socket
> API became as ubiquitous as it is today.
>
>> * I need the ability to bind a Socket to a random port number (0).
>> Because ZMQ doesn't support
>> this, I implemented a bind_to_random_port method that tries random
>> ports in a range until
>> it finds one and then returns that port number.
>>
>> http://github.com/ellisonbg/pyzmq/blob/master/zmq/_zmq.pyx#L287
>
> Hm, this one is interesting, however, I am afraid that allowing for this
> kind of functionality breaks the big picture.
>
> In short, the idea is that messaging "channels" (in this case ports) are
> assigned more or less statically. Business "channel" (say "NASDAQ quote
> feed") is mapped to specific "address" (say "port 3456").
>
> Think of assigning IP numbers or domain names. These are more or less
> statically defined and thus allow for resolution on Internet scale. With
> dynamically assigned addresses this kind of resolution is not possible
> AFAICS.
>
> This is an area for future research though, so feel free to discuss.
>
>> * My interface to poll in modeled on Python's built-in select.poll module:
>>
>> It has a Poller class which you create and then call register to add
>> fds/sockets:
>>
>> p = Poller()
>> p.register(s1)
>> p.register(s2)
>> p.poll(timeout=10)
>> p.unregister(s1)
>>
>> * I have added additional methods to the Socket object to serialize
>> Python objects and send messages in various formats: send_json,
>> recv_json (json) and send_pyobj, recv_pyobj (pickle).
>>
>> Overall, the core API of the Python bindings follows the C/C++ very
>> closely though.
>>
>> I am willing to change some of the core API of the Python bindings if
>> needed but I do think it is important
>> for each language to create an API that follows the spirit of the
>> language.
>
> Ack. API for each language should place as little barrier for adoption
> by users of the language as possible. At the same time is should keep as
> close to underlying C API as to make it easy for users to refer to C API
> documentation.
>
> Martin
>
> _______________________________________________
> zeromq-dev mailing list
> [email protected]
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev