diff options
author | Alex Grönholm <alex.gronholm@nextday.fi> | 2022-07-27 01:25:26 +0300 |
---|---|---|
committer | Alex Grönholm <alex.gronholm@nextday.fi> | 2022-07-27 13:02:08 +0300 |
commit | a72f2e7466cb59af91ca45c5b81d3cf539552366 (patch) | |
tree | 44f7f947e46e2a21520132abdff02f7a9cb0ab49 /src | |
parent | 032e5ef97fb252227717f21a7150cc73e19f41c3 (diff) | |
download | apscheduler-a72f2e7466cb59af91ca45c5b81d3cf539552366.tar.gz |
Implemented (un)marshalling for events
This fixes JSON (de)serialization of certain events.
Diffstat (limited to 'src')
-rw-r--r-- | src/apscheduler/eventbrokers/base.py | 6 | ||||
-rw-r--r-- | src/apscheduler/events.py | 16 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/apscheduler/eventbrokers/base.py b/src/apscheduler/eventbrokers/base.py index 3aeee77..5f2ece1 100644 --- a/src/apscheduler/eventbrokers/base.py +++ b/src/apscheduler/eventbrokers/base.py @@ -56,11 +56,11 @@ class DistributedEventBrokerMixin: _logger: Logger def generate_notification(self, event: Event) -> bytes: - serialized = self.serializer.serialize(attrs.asdict(event)) + serialized = self.serializer.serialize(event.marshal(self.serializer)) return event.__class__.__name__.encode("ascii") + b" " + serialized def generate_notification_str(self, event: Event) -> str: - serialized = self.serializer.serialize(attrs.asdict(event)) + serialized = self.serializer.serialize(event.marshal(self.serializer)) return event.__class__.__name__ + " " + b64encode(serialized).decode("ascii") def _reconstitute_event(self, event_type: str, serialized: bytes) -> Event | None: @@ -85,7 +85,7 @@ class DistributedEventBrokerMixin: return None try: - return event_class(**kwargs) + return event_class.unmarshal(self.serializer, kwargs) except Exception: self._logger.exception("Error reconstituting event of type %s", event_type) return None diff --git a/src/apscheduler/events.py b/src/apscheduler/events.py index 408089e..6aba147 100644 --- a/src/apscheduler/events.py +++ b/src/apscheduler/events.py @@ -2,21 +2,37 @@ from __future__ import annotations from datetime import datetime, timezone from functools import partial +from typing import Any from uuid import UUID import attrs from attrs.converters import optional +from . import abc from .converters import as_aware_datetime, as_uuid from .enums import JobOutcome +def serialize(inst, field, value): + if isinstance(value, frozenset): + return list(value) + + return value + + @attrs.define(kw_only=True, frozen=True) class Event: timestamp: datetime = attrs.field( factory=partial(datetime.now, timezone.utc), converter=as_aware_datetime ) + def marshal(self, serializer: abc.Serializer) -> dict[str, Any]: + return attrs.asdict(self, value_serializer=serialize) + + @classmethod + def unmarshal(cls, serializer: abc.Serializer, marshalled: dict[str, Any]) -> Event: + return cls(**marshalled) + # # Data store events |