Skip to content

Commit

Permalink
Updated Compact Configuration (#546)
Browse files Browse the repository at this point in the history
Updated compact serialization configuration
  • Loading branch information
yuce committed Apr 26, 2022
1 parent a0b3eab commit bb2692c
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 127 deletions.
1 change: 1 addition & 0 deletions black.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exclude = '''
| \.mypy_cache
| \.tox
| \.venv
| venv
| _build
| buck-out
| build
Expand Down
15 changes: 9 additions & 6 deletions docs/serialization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,26 +149,29 @@ Then, a serializer for it can be implemented as below:
from hazelcast.serialization.api import CompactSerializer, CompactWriter, CompactReader
class EmployeeSerializer(CompactSerializer[Employee]):
def read(self, reader: CompactReader) -> Employee:
def read(self, reader: CompactReader):
name = reader.read_string("name")
age = reader.read_int32("age")
return Employee(name, age)
def write(self, writer: CompactWriter, obj: Employee) -> None:
def write(self, writer: CompactWriter, obj: Employee):
writer.write_string("name", obj.name)
writer.write_int32("age", obj.age)
def get_type_name(self) -> str:
def get_type_name(self):
return "employee"
def get_class(self):
return Employee
The last step is to register the serializer in the client configuration.

.. code:: python
client = HazelcastClient(
compact_serializers={
Employee: EmployeeSerializer(),
}
compact_serializers=[
EmployeeSerializer(),
]
)
A schema will be created from the serializer, and a unique schema identifier
Expand Down
35 changes: 20 additions & 15 deletions examples/serialization/compact_serialization_example.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from hazelcast import HazelcastClient
from hazelcast.serialization.api import CompactSerializer, CompactWriter, CompactReader
from hazelcast.serialization.api import (
CompactSerializer,
CompactWriter,
CompactReader,
)


class Address:
Expand All @@ -8,7 +12,7 @@ def __init__(self, city: str, street: str):
self.street = street

def __repr__(self):
return f"Address(city='{self.city}', street='{self.street}'"
return f"Address(city='{self.city}', street='{self.street}')"


class Employee:
Expand All @@ -18,45 +22,46 @@ def __init__(self, name: str, age: int, address: Address):
self.address = address

def __repr__(self):
return f"Employee(name='{self.name}', age={self.age}, address={self.address}"
return f"Employee(name='{self.name}', age={self.age}, address={self.address})"


class AddressSerializer(CompactSerializer[Address]):
def read(self, reader: CompactReader) -> Address:
def read(self, reader: CompactReader):
city = reader.read_string("city")
street = reader.read_string("street")
return Address(city, street)

def write(self, writer: CompactWriter, obj: Address) -> None:
def write(self, writer: CompactWriter, obj: Address):
writer.write_string("city", obj.city)
writer.write_string("street", obj.street)

def get_type_name(self) -> str:
def get_type_name(self):
return "Address"

def get_class(self):
return Address


class EmployeeSerializer(CompactSerializer[Employee]):
def read(self, reader: CompactReader) -> Employee:
def read(self, reader: CompactReader):
name = reader.read_string("name")
age = reader.read_int32("age")
address = reader.read_compact("address")
return Employee(name, age, address)

def write(self, writer: CompactWriter, obj: Employee) -> None:
def write(self, writer: CompactWriter, obj: Employee):
writer.write_string("name", obj.name)
writer.write_int32("age", obj.age)
writer.write_compact("address", obj.address)

def get_type_name(self) -> str:
def get_type_name(self):
return "Employee"

def get_class(self):
return Employee

client = HazelcastClient(
compact_serializers={
Address: AddressSerializer(),
Employee: EmployeeSerializer(),
}
)

client = HazelcastClient(compact_serializers=[AddressSerializer(), EmployeeSerializer()])

employees = client.get_map("employees").blocking()

Expand Down
21 changes: 12 additions & 9 deletions examples/sql/sql_compact_example.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import dataclasses

from hazelcast import HazelcastClient
from hazelcast.serialization.api import CompactSerializer, CompactWriter, CompactReader
from hazelcast.serialization.api import (
CompactSerializer,
CompactWriter,
CompactReader,
)


@dataclasses.dataclass
Expand All @@ -11,24 +15,23 @@ class Person:


class PersonSerializer(CompactSerializer[Person]):
def read(self, reader: CompactReader) -> Person:
def read(self, reader: CompactReader):
name = reader.read_string("name")
age = reader.read_int32("age")
return Person(name, age)

def write(self, writer: CompactWriter, obj: Person) -> None:
def write(self, writer: CompactWriter, obj: Person):
writer.write_string("name", obj.name)
writer.write_int32("age", obj.age)

def get_type_name(self) -> str:
def get_type_name(self):
return "Person"

def get_class(self):
return Person

client = HazelcastClient(
compact_serializers={
Person: PersonSerializer(),
}
)

client = HazelcastClient(compact_serializers=[PersonSerializer()])

client.sql.execute(
"""
Expand Down
11 changes: 5 additions & 6 deletions hazelcast/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ class SomeSerializable(Portable):
}
})
compact_serializers (dict[typing.Type, hazelcast.serialization.api.CompactSerializer]):
Dictionary of classes to be serialized with Compact serialization
to Compact serializers.
compact_serializers (list[hazelcast.serialization.api.CompactSerializer]):
List of Compact serializers.
.. code-block:: python
Expand All @@ -209,9 +208,9 @@ class FooSerializer(CompactSerializer[Foo]):
pass
client = HazelcastClient(
compact_serializers={
Foo: FooSerializer(),
},
compact_serializers=[
FooSerializer(),
],
)
class_definitions (`list[hazelcast.serialization.portable.classdef.ClassDefinition]`):
Expand Down
14 changes: 5 additions & 9 deletions hazelcast/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ def __init__(self):
self._creds_password = None
self._token_provider = None
self._use_public_ip = False
self._compact_serializers: typing.Dict[typing.Type, CompactSerializer] = {}
self._compact_serializers: typing.List[CompactSerializer] = []

@property
def cluster_members(self):
Expand Down Expand Up @@ -1369,19 +1369,15 @@ def use_public_ip(self, value):
raise TypeError("use_public_ip must be a boolean")

@property
def compact_serializers(self) -> typing.Dict[typing.Type, CompactSerializer]:
def compact_serializers(self) -> typing.List[CompactSerializer]:
return self._compact_serializers

@compact_serializers.setter
def compact_serializers(self, value: typing.Dict[typing.Type, CompactSerializer]) -> None:
if isinstance(value, dict):
for clazz, serializer in value.items():
if not isinstance(clazz, type):
raise TypeError("Keys of compact_serializers must be classes")

def compact_serializers(self, value: typing.List[CompactSerializer]) -> None:
if isinstance(value, list):
for serializer in value:
if not isinstance(serializer, CompactSerializer):
raise TypeError("Values of compact_serializers must be CompactSerializer")

self._compact_serializers = value
else:
raise TypeError("compact_serializers must be a dict")
Expand Down
8 changes: 8 additions & 0 deletions hazelcast/serialization/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3059,6 +3059,14 @@ def write(self, writer: CompactWriter, obj: CompactSerializableClass) -> None:
to write.
"""

@abc.abstractmethod
def get_class(self) -> typing.Type[CompactSerializableClass]:
"""Returns the class that this serializer reads or writes.
Returns:
The class that this serializer reads or writes.
"""

@abc.abstractmethod
def get_type_name(self) -> str:
"""Returns the unique type name associated with
Expand Down
8 changes: 3 additions & 5 deletions hazelcast/serialization/compact.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@


class CompactStreamSerializer(BaseSerializer):
def __init__(self, compact_serializers: typing.Dict[typing.Type, CompactSerializer]):
self._type_to_serializer = compact_serializers
self._type_name_to_serializer: typing.Dict[str, CompactSerializer] = {
serializer.get_type_name(): serializer for serializer in compact_serializers.values()
}
def __init__(self, compact_serializers: typing.List[CompactSerializer]):
self._type_to_serializer = {s.get_class(): s for s in compact_serializers}
self._type_name_to_serializer = {s.get_type_name(): s for s in compact_serializers}
self._type_to_schema: typing.Dict[typing.Type, Schema] = {}
self._id_to_schema: typing.Dict[int, Schema] = {}

Expand Down
2 changes: 1 addition & 1 deletion hazelcast/serialization/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def __init__(
self._registration_lock = threading.RLock()
self._int_type_id = _int_type_to_type_id.get(config.default_int_type, None)

self._compact_types = set(config.compact_serializers.keys())
self._compact_types = {c.get_class() for c in config.compact_serializers}

def serializer_by_type_id(self, type_id):
"""Find and return the serializer for the type-id
Expand Down
54 changes: 28 additions & 26 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,31 @@ def wait_until_rc_is_ready():
raise Exception("Remote controller failed to start.")


if __name__ == "__main__":
with open("rc_stdout.log", "w") as rc_stdout:
with open("rc_stderr.log", "w") as rc_stderr:
rc_process = start_rc(rc_stdout, rc_stderr)
try:
wait_until_rc_is_ready()
sys.stdout.flush()

args = [
"pytest",
"--cov=hazelcast",
"--cov-report=xml",
]

enterprise_key = os.environ.get("HAZELCAST_ENTERPRISE_KEY", None)
if not enterprise_key:
args.extend(["-m", "not enterprise"])

process = subprocess.run(args)
rc_process.kill()
rc_process.wait()
sys.exit(process.returncode)
except:
rc_process.kill()
rc_process.wait()
raise
with open("rc_stdout.log", "w") as rc_stdout:
with open("rc_stderr.log", "w") as rc_stderr:
rc_process = start_rc(rc_stdout, rc_stderr)
try:
wait_until_rc_is_ready()
sys.stdout.flush()

args = [
"pytest",
"--cov=hazelcast",
"--cov-report=xml",
]
args.extend(sys.argv[1:])

enterprise_key = os.environ.get("HAZELCAST_ENTERPRISE_KEY", None)
if not enterprise_key:
args.extend(["-m", "not enterprise"])

print(f"Args: {' '.join(args)}")

process = subprocess.run(args)
rc_process.kill()
rc_process.wait()
sys.exit(process.returncode)
except:
rc_process.kill()
rc_process.wait()
raise

0 comments on commit bb2692c

Please sign in to comment.