-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
You api could be greatly improved #106
Comments
Agreed, and this is why this lib is still in version 0.xx: because the API is not clearly defined and not frozen. We first want to implement the specs and make sure it is efficient. Don't hesitate to contribute; I think trying to improve the code and design together is the beauty of opensource. As you may notice, maintaining an opensource library is very time-consuming and requires a lot of effort. Don't forget you're talking to humans, not to robots :)) |
@dzen Yes, very consuming, I agree. That's what's kind of sad to me, so much effort is kind of wasted. Glad to hear, that you would allow contributions. I'll try to contribute. Actually, I'm rewriting parts of code right now. See what I can make myself =) |
@purpleP try to not rewrite everything, since it will be hard to read Note: we can't hide the AMQP wording at all, since its very important to be sure RabbitMQ is behaving nicely with a low level lib. |
@dzen I don't understand how hiding implementation makes someone unsure about RabbitMQ behaviour. And by the way, rabbit isn't only implementation (just in case). Second. I've started to play with the code. You can see current state in my fork. |
@dzen I can see xml schema or something like that, that have description of frames etc, but not the types and serialization stuff. |
Hello @purpleP, I've got multiple points:
I really feel you're angry, and sincerely I do not like your aggressiveness, but I think you're here to help. Note: I did'nt find any commits in your branches, and I fear you already have a lot's of diff in your repository making it really hard to review. |
Hi guys, +1 to not hiding AMQP wording, because it makes a lot easier to use this lib with AMQP reference guide and comparison with other implementations of the protocol, while lib's own docs are not available. When I was needed to hide protocol details under abstraction layer, I just wrote a quick wrapper. |
@anti1869 yes it's my point :) |
@dzen I'm not angry, don't worry. I'll give an example of what I'm talking about and why I'm asking.
You're using this to decide how to read table and array items, but there's no read_unsigned_long_long function. There is however read_signed_long_long function. Maybe you've meant to type that. I don't know and can't check that, because can't find this kind of info anywhere. I've tried to see pika's library implementation, but that's not a 100 % guarantee. As for diffs. I have exactly one diff now basically. I've created new file Quick question that's related to my first question. When writing tables
You don't have writers for all possible types. Is this the part of the spec? And if it's not wouldn't it be better to write more optimally in space? Like if the string is short enough that write shortstr type or if int is small enough then write short type etc.? Oh, and It would probably be better to ask this upfront. why there is no 'write_array' function? Client never write arrays? My plan right now is to add tests for decoding (I don't think you have any), probably rewrite tests for encoding. It could be made into single test for example.
One other thing. After I'm done with encoding/decoding module it will be possible to memoize encoding and decoding of types and frames. Do you think this could be useful? I think it can, because typical amqp application uses limited set of different messages types. And because of that there would probably be a lot of identical headers and stuff like that. |
I'm not against it, but ATM no-one (@dzen and I included) did any sort of profiling on the code base (other than 30,000ft in #70) and I'd rather avoid premature optimizations. Especially if the long-term maintenance cost is high. Right now, the 2 areas I'd like to focus on are:
Thanks for your suggestions (and patches!) |
@dzen memoization is done with I thought about that rewriting from the low-level to high level will bring fruits later, but It's easier to me to work that way. My workflow is something like:
|
I prefer the library to be as low-level as possible, it's easy to write high-level API over low-level one, but the opposite is not true. For example, another asynchronous await queue.bind(exchange, routing_key) It's pythonic, fun and dandy, but completely unusable, because it's not possible to create the binding without prepared queue instance and that's not always what you wanted. With low-level API that for queue in rabbitmq.queues:
await self.declare_queue(**queue)
for exchange in rabbitmq.exchanges:
await self.declare_exchange(**exchange)
for binding in rabbitmq.bindings:
await self.bind_queue(**binding) It's a snippet from my current project and I've implemented high level API over So, if you gonna implement high-level API please leave the current one untouched. Thanks! :) |
I've tried asynqp at first, but they for some reason don't allow coroutines to be message handlers, which is also insane (that's defiles the purpose of the library, don't you think?).
Your library on the other hand is sane enough to allow it, but the api...
I'll give examples.
channel.exchange_declare(exchange_name='logs', type_name='fanout'
channel.declare_exchange(name='logs', type='fanout')
. And if you want to be anal and explicit maketype
Enum.result
is a Mapping? What? It should at least be a namedtuple. Mapping is a thing that can map arbitrary keys to arbitrary values, that's not what you're doing here. You task is more specific than that.But this gets better. To get queue name you need to get value by
'queue'
key. Why not'name'
at least?queue_bind
takes exchange name, but not exchange object. That's also non intuitive and inconvinient.You know when you send tcp frames somewhere and then await for response there's a name for it. Request. return await self.send_request('exchange_delete', frame, ...)`
That's just from skimming the sources.
I hope you're won't be upset by my critique. I'd like to say that it came from amusement, because It's not obvious to me, how could you handle all this nitty-gritty low level details like tcp sockets, sending frames, serialization etc without problems, but fail to provide an intuitive, easy to use and beautiful api.
The text was updated successfully, but these errors were encountered: