I'm experiencing a strange behaviour while trying to serialize some data to send as argument to a remote procedure using Nameko and rabbitmq to a microservice:
A semplification of the problem structured into 3 files under a dir named project
:
serializer.py, the custom json encoding/decoding objects
from enum import Enum
import json
from project.service import CustomEnum
class CustomEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, CustomEnum):
# return {'__enum__': str(o)}
return {'__enum__': o.name}
return {'__{}__'.format(o.__class__.__name__): o.__dict__}
class CustomDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self,
object_hook=self.object_hook,
*args, **kwargs)
def object_hook(self, o):
if '__enum__' in o:
return CustomEnum[o['__enum__']]
# name, member = o['__enum__'].split('.')
# return getattr(ENUMS[name], member)
return o
service.py, the basic microservice
from enum import Enum
from nameko.rpc import rpc
import json
from project.serializer import CustomDecoder
class CustomEnum(Enum):
A = 0
B = 1
class Service(object):
name = "service"
@rpc
def get_enum(self, enum_type):
enum_type = json.loads(enum_type, cls=CustomDecoder)
if enum_type == CustomEnum.A:
return "A"
elif enum_type == CustomEnum.B:
return "B"
return "NO ENUM"
Nameko shell to try out, after starting a rabbitMQ docker instance and nameko run of the service by following these steps:
$ docker run -d --hostname rabbit --name my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
$ nameko run project.service --broker amqp://guest:guest@localhost
$ nameko shell --broker amqp://guest:guest@localhost
Here the shell output after testing it:
In [1]: import json
In [2]: from project.serializer import CustomEncoder
In [3]: from project.service import CustomEncoder
In [4]: serialized = json.dumps(CustomEnum.A, cls=CustomEncoder)
In [5]: n.rpc.service.get_enum(serialized)
NO ENUM
It seems that after being deserialized on the remote procedure type(enum_type) == type(CustomEnum)
gives False, while trying it out in the nameko shell it perfectly serialized and deserialize the enum subclass type.
Could it have something to do with the serialization of already serialized data by nameko itself? I know I should register the custom serializer to the kombu.serialization.register
but I'm stuck to this and I'd like to know why this happen.