summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2022-07-27 01:25:26 +0300
committerAlex Grönholm <alex.gronholm@nextday.fi>2022-07-27 13:02:08 +0300
commita72f2e7466cb59af91ca45c5b81d3cf539552366 (patch)
tree44f7f947e46e2a21520132abdff02f7a9cb0ab49 /src
parent032e5ef97fb252227717f21a7150cc73e19f41c3 (diff)
downloadapscheduler-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.py6
-rw-r--r--src/apscheduler/events.py16
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