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

Perform custom deserializations #1

Open
wants to merge 2 commits into
base: v5.2.4
Choose a base branch
from
Open

Perform custom deserializations #1

wants to merge 2 commits into from

Conversation

jbkkd
Copy link

@jbkkd jbkkd commented Oct 3, 2023

Items with these values will start appearing in a later version of kombu (5.3.0 onwards).

To migrate our kombu installation safely, we first add support for deserializing these objects, deploy that, and then we can migrate kombu to version 5.3.0 safely.

@@ -11,25 +11,26 @@

from vine.utils import wraps

from kombu.log import get_logger
from kombu.log import get_logg
Copy link

Choose a reason for hiding this comment

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

🤔 Is it a typo?

Copy link
Author

Choose a reason for hiding this comment

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

🤦 yes

Copy link
Author

Choose a reason for hiding this comment

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

surprised that our build is working despite this

@jbkkd jbkkd force-pushed the v5.2.4-patched branch 2 times, most recently from 7c604f1 to 2c73452 Compare October 4, 2023 13:28
@@ -13,23 +13,24 @@

from kombu.log import get_logger

try:

Choose a reason for hiding this comment

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

No change necessary, but to save us the conditional handling of ZoneInfo, as we only want UTC we could use Python's datetime.timezone.utc.

Choose a reason for hiding this comment

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

I am +1 on this, seems like a less risky change than introducing zoneinfo

Copy link
Author

@jbkkd jbkkd Oct 5, 2023

Choose a reason for hiding this comment

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

You're right that we could do that, however this change is taken directly from kombu:
celery#1680
Seeing that ZoneInfo will be added once we upgrade regardless, we might as well do this now. I prefer sticking to whatever kombu is doing even if it isn't the best solution.

kombu/utils/json.py Outdated Show resolved Hide resolved
@@ -69,6 +69,19 @@ def dumps(s, _dumps=json.dumps, cls=None, default_kwargs=None, **kwargs):
**dict(default_kwargs, **kwargs))


def object_hook(dct):

Choose a reason for hiding this comment

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

this looks wrong to me. Shouldn't we be checking for the "__type__" and "__value__" keys in the dict?

like here https://github.com/celery/kombu/blob/v5.3.2/kombu/utils/json.py#L60-L69

Also, shouldn't this function be returning strings?

Copy link
Author

@jbkkd jbkkd Oct 5, 2023

Choose a reason for hiding this comment

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

Ah yes, I based my changes on this pr:
celery#1516
But I see now that main has changed that behaviour

Copy link
Author

Choose a reason for hiding this comment

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

As for returning strings - we're going to do that in kraken directly rather than through a patch to kombu, so we won't have to re-patch on every new kombu upgrade

Copy link
Author

Choose a reason for hiding this comment

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

I've changed the PR to make it more similar to what's currently on the main branch

Choose a reason for hiding this comment

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

I've changed the PR to make it more similar to what's currently on the main branch

I don't think we should do this. This PR should keep kombu as close as possible to 5.2.4 (not main), with the minimal changes needed to handle {"__type__": ..., "__value__": ...} objects.

Choose a reason for hiding this comment

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

As for returning strings - we're going to do that in kraken directly rather than through a patch to kombu, so we won't have to re-patch on every new kombu upgrade

We're doing that in kraken only once kombu is upgraded to 5.3.0+ and this patch is thrown away.
This patch is for kraken still running kombu 5.2.4, it needs to be able to receive the special objects and return strings for the workers e.g. receive

{"__type__": "datetime", "__value__": "2023-09-29T00:45:25.412564Z"}

and return the string "2023-09-29T00:45:25.412564Z" since that is what the workers expect

Copy link
Author

@jbkkd jbkkd Oct 9, 2023

Choose a reason for hiding this comment

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

I have a slightly different approach in mind, with the following steps:

  1. Update kraken-core to use this branch, and also add the register_type on the same PR in kraken-core. This means that rather than needing this (kombu) branch to do the the __datetime__ deserialization, this will be done in kraken-core using the same method we'll eventually use once >5.3.0 is live.
  2. Deploy the kombu upgrade PR, which will only include the kombu upgrade and nothing more.

It's a slightly different approach to the on you're suggesting (which is doing the datetime deserialization in this branch), but achieves the same results - we'll be able to safely rollback at any point whilst always returning str for datetimes and UUIDs.

I've tested these changes locally. First, I installed this patched version, scheduled a task with this version that sends a datetime argument, then installed 5.2.4 again and ran the celery worker. The argument was deserialized as an str.
Then I did the same thing with 5.3.2 - I scheduled as task on that version, and ran the worker with the patched version, and again the task was deserialized as str.

I've updated the kraken-core PR related to this to reflect that.

jamesbeith
jamesbeith previously approved these changes Oct 5, 2023
@jamesbeith jamesbeith dismissed their stale review October 5, 2023 02:58

Only meant to leave a commenting review.

jbkkd added 2 commits October 5, 2023 12:03
Items with these values will start appearing in a later version of kombu (5.3.0 onwards).

To migrate our kombu installation safely, we first add support for deserializing these objects, deploy that, and then we can migrate kombu to version 5.3.0 safely.
It's been removed in this PR:
celery#1680

Moreover, the test.txt syntax is invalid with our version of setuptools
Copy link

@seddonym seddonym left a comment

Choose a reason for hiding this comment

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

Omer has talked me through the overall approach, and I think while there is more than one way to tackle this, it seems to me a decent one - on the basis that this fork won't stick around for very long.

This doesn't need an approval, but I'm approving https://github.com/octoenergy/kraken-core/pull/105425 instead. I think that one could do with a second thumbs up from @LincolnPuzeyCC, who is closer to the details.

Comment on lines +127 to +143
# NOTE: datetime should be registered before date,
# because datetime is also instance of date.
register_type(datetime, "datetime", datetime.datetime.isoformat, datetime.datetime.fromisoformat)
register_type(
datetime.date,
"date",
lambda o: o.isoformat(),
lambda o: datetime.datetime.fromisoformat(o).date(),
)
register_type(datetime.time, "time", lambda o: o.isoformat(), datetime.time.fromisoformat)
register_type(Decimal, "decimal", str, Decimal)
register_type(
uuid.UUID,
"uuid",
lambda o: {"hex": o.hex},
lambda o: uuid.UUID(**o),
)
Copy link

@LincolnPuzeyCC LincolnPuzeyCC Oct 18, 2023

Choose a reason for hiding this comment

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

given this is our fork of kombu you could remove this part since these registrations are overwritten by kraken anyway - and these contain the behavior we don't want - kombu de-coding into typed objects rather than strings.

@LincolnPuzeyCC
Copy link

LincolnPuzeyCC commented Oct 18, 2023

Left one suggestion - but otherwise looks fine - this will let kraken handle {'__type__': ..., '__value__': ...} dicts once kombu is upgraded ✅ - but I also have a different comment on the kraken-core PR

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.

5 participants