Skip to content
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

Allow sending multiple messages in bulk #400

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

olzhasar
Copy link

@olzhasar olzhasar commented Oct 3, 2024

This is a draft implementation for #399

It adds support for sending multiple messages to the core layer only. It probably does not make much sense to add that to the pubsub layer, cause the underlying redis publish command only supports a single message.

I had to add an additional argument to the lua script for group sending, I hope that's not a big deal. But let me know if it is, I guess we can make the script dynamic.

Copy link
Collaborator

@bigfootjon bigfootjon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks reasonable to me. I'm not very familiar with Lua, but as long as the test suite covers this and it works I think I'm ok with it

channels_redis/core.py Outdated Show resolved Hide resolved
channels_redis/core.py Show resolved Hide resolved
channels_redis/core.py Outdated Show resolved Hide resolved
channels_redis/core.py Outdated Show resolved Hide resolved
@olzhasar olzhasar force-pushed the bulk-sending branch 2 times, most recently from 5fa875f to 15b50ae Compare October 8, 2024 11:50
Copy link
Collaborator

@bigfootjon bigfootjon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carltongibson: when you have a moment could you take a look at this PR? I think it's ready for you

"""
Convert a passed message arg to a tuple of messages.
"""
if not isinstance(message, dict) and hasattr(message, "__iter__"):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use isinstance(message, collections.abc.Iterable here instead? I think that would make this a bit more readable

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can iterate a dict no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, python dict is an instance of collections.abc.Iterable

Copy link
Member

@carltongibson carltongibson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two queries.

  1. Are we sure about changing the signature of the existing send, rather than adding a new method here? Like, we don't use type hints yet, but think through the change there... from single message type to a union of that and an iterable of such... — does that look like a change we'd make?
  2. Do we need to update the docs and spec for channel layers here? https://channels.readthedocs.io/en/latest/channel_layer_spec.html — I'd think we do.

Ref 1, I'm slightly wary of adjusting the existing method, as we've had regressions in the Lua scripting before, which are hard to anticipate outside of production.

"""
Convert a passed message arg to a tuple of messages.
"""
if not isinstance(message, dict) and hasattr(message, "__iter__"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can iterate a dict no?

Comment on lines 232 to 243
def _parse_messages(self, message):
"""
Convert a passed message arg to a tuple of messages.
"""
if not isinstance(message, dict) and hasattr(message, "__iter__"):
return tuple(message)
return (message,)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a shame to consume the iterator only to loop over it again in the for message in messages loop. 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will rewrite that

@olzhasar
Copy link
Author

olzhasar commented Oct 19, 2024

@carltongibson

Are we sure about changing the signature of the existing send, rather than adding a new method here? Like, we don't use type hints yet, but think through the change there... from single message type to a union of that and an iterable of such... — does that look like a change we'd make?

I initially thought the same way and used two separate methods, but @bigfootjon's comment made me change my mind on that. I agreed cause I thought that typing is out of scope for everything django-related 😁

I'm slightly wary of adjusting the existing method, as we've had regressions in the Lua scripting before

This is a legit concern. I'm actually okay with closing this PR if risks outweigh possible benefits from this feature. For my own use case, I've already made a workaround in place :)

@bigfootjon
Copy link
Collaborator

I think the benefits are there so I'd like to see this landed, but if @carltongibson would rather be conservative here I'll defer to his wisdom. @olzhasar would you mind undoing my recommendation and split up each method? Additionally, when you split things up please split the Lua script as well to make sure we don't regress

@carltongibson
Copy link
Member

("Wisdom" here means only "been bitten by more innocent looking things enough times to be wary" 😅)

@olzhasar olzhasar force-pushed the bulk-sending branch 3 times, most recently from f2cec18 to cbe1081 Compare October 27, 2024 22:02
@olzhasar
Copy link
Author

I think the benefits are there so I'd like to see this landed, but if @carltongibson would rather be conservative here I'll defer to his wisdom. @olzhasar would you mind undoing my recommendation and split up each method? Additionally, when you split things up please split the Lua script as well to make sure we don't regress

I've updated the PR splitting the methods as discussed, and preserving the old lua script for group_send.
Tried to reuse as much code as I could in the group sending methods. It's still not ideal, but going any further would likely lead to a complete redesign, which arguably may not be worth it for this particular feature.

Copy link
Collaborator

@bigfootjon bigfootjon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I'll let @carltongibson give it one final lookover

@amirreza8002
Copy link

amirreza8002 commented Oct 29, 2024

hi
is this supposed to be messages? or message?

and this supposed to be args? or *args?

@olzhasar
Copy link
Author

hi is this supposed to be messages? or message?

and this supposed to be args? or *args?

Hey,

The first one is a great catch, fixed that.

As for the second thing, it generally can work either way, but I believe the current version leaves more room for future signature changes, e.g. introducing additional positional arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants