Skip to content

fix (#2061): used struct.pack to encode headers length into binary #2287

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ilya-4real
Copy link
Contributor

Description

Fixes bug of serialization/deserialization of binary data. Logic of working with plain text and json remains the same so as not to break existing API. But when user provides binary data, 4-bytes unsigned int is added to indicate the length of headers needed by FastStream.
May be it's needed to add new type to ContentType enum to make this solution more verbose

Fixes #2061

Type of change

Please delete options that are not relevant.

  • Bug fix (a non-breaking change that resolves an issue)

Checklist

  • My code adheres to the style guidelines of this project (scripts/lint.sh shows no errors)
  • I have conducted a self-review of my own code
  • I have made the necessary changes to the documentation
  • My changes do not generate any new warnings
  • I have added tests to validate the effectiveness of my fix or the functionality of my new feature
  • Both new and existing unit tests pass successfully on my local environment by running scripts/test-cov.sh
  • I have ensured that static analysis tests are passing by running scripts/static-analysis.sh
  • I have included code examples to illustrate the modifications

@CLAassistant
Copy link

CLAassistant commented Jun 11, 2025

CLA assistant check
All committers have signed the CLA.

@ilya-4real ilya-4real marked this pull request as ready for review June 19, 2025 12:23
@ilya-4real
Copy link
Contributor Author

ilya-4real commented Jun 19, 2025

Is it correct way to deprecate JSON format? Or should it use JSON by default and fallback to new format in case of parsing error?

parsed_data = json_loads(data)
data = parsed_data["data"].decode()
headers = parsed_data["headers"]
warnings.warn(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think, that we should show deprecation message here. Users do not select the format they consume.

@@ -90,31 +149,72 @@ def encode(
reply_to: Optional[str],
headers: Optional["AnyDict"],
correlation_id: str,
to_json: bool = False,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not public API object, should we add json-encoder option here?
I think, we can use just a binary format

[Number of headers: 16 bit big-endian int]
# headers
[Header key length: 16 bit big-endian int]
[Header key: UTF-8 string]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Look like the format is incorrect. We should use [key:value, key:value] instead of [key, key, value, value].
Also, please use the same words everywhere: 16 bit big-endian int or 16 big-endian bit int

@@ -0,0 +1,240 @@
# Dealing with message encoded by FastStream

To provide such great features as observability and many others **FastStream** needs to add extra data to your message, but suddenly **Redis** doesn't have any option to send it except the message itself. Since that, **FastStream** uses it's own binary format for messages that supports any type of data that you are going to use.
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should note, that raw messages are OK as well, but they doesn't support headers-based features

from tests.brokers.base.parser import CustomParserTestcase


@pytest.mark.redis
class TestCustomParser(CustomParserTestcase):
broker_class = RedisBroker


@pytest.mark.redis
Copy link
Collaborator

Choose a reason for hiding this comment

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

This marker should be used only if test require connection to Redis



@pytest.mark.redis
class TestRedisRawMessage:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Current test can be just a function as I can see

@ilya-4real
Copy link
Contributor Author

@Lancetnik please review

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.

Bug: Custom Serialization/Deserialization logic in Redis doesn't work unless UTF-8 serializable
3 participants