nacos-group / nacos-sdk-python

nacos python sdk
Apache License 2.0
352 stars 134 forks source link

配置中心,增加add_config_watcher python3.10 监听报TypeError: cannot pickle '_thread.RLock' object 有大佬解决么 #124

Open Felix1029 opened 1 year ago

Felix1029 commented 1 year ago

Traceback (most recent call last): File "/Users/oker/Documents/PyProject/ui-autotest-cases/libs/x_nacos.py", line 80, in client.add_config_watcher(AB_TEST_CITY_VERSION_CONFIG, NACOS_CONFIG_GROUP, utest_cb) # 这个必须放在main里面完成 File "/Users/oker/Documents/PyProject/ui-autotest-cases/venv/lib/python3.10/site-packages/nacos/commons.py", line 10, in synced_func return func(*args, *kws) File "/Users/oker/Documents/PyProject/ui-autotest-cases/venv/lib/python3.10/site-packages/nacos/client.py", line 520, in add_config_watcher self.add_config_watchers(data_id, group, [cb], content) File "/Users/oker/Documents/PyProject/ui-autotest-cases/venv/lib/python3.10/site-packages/nacos/commons.py", line 10, in synced_func return func(args, **kws) File "/Users/oker/Documents/PyProject/ui-autotest-cases/venv/lib/python3.10/site-packages/nacos/client.py", line 566, in add_config_watchers puller.start() File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 121, in start self._popen = self._Popen(self) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/context.py", line 224, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/context.py", line 288, in _Popen return Popen(process_obj) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/popen_spawn_posix.py", line 32, in init super().init(process_obj) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/popen_fork.py", line 19, in init self._launch(process_obj) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/popen_spawn_posix.py", line 47, in _launch reduction.dump(process_obj, fp) File "/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) TypeError: cannot pickle '_thread.RLock' object

runzhi214 commented 1 year ago

Confirmed. 3.9.12也遇到同样的报错了。

add_config_watcher(data_id="application.yaml", group="DEFAULT_GROUP", cb=lambda x: print(x))

注册服务、获取配置、发送心跳都正常

runzhi214 commented 1 year ago

问题定位到了,就是Python版本不支持,换成Python3.7.3的虚拟环境,不再报这个错误。

runzhi214 commented 1 year ago

更多测试: 3.8.15 (default, Nov 24 2022, 09:04:07) [Clang 14.0.6 ] 同样出现这个报错。作者在README标注了支持3.6/3.7应该是知道升级到3.8之后某些特性变了,因此不兼容。等我研究下怎么改

runzhi214 commented 1 year ago

你应该也是用的也是非Windows系统吧?这个问题是由几个不可序列化的对象导致的。 一个quick patch可以这样,给nacos-sdk-python的client.py增加下列方法,在序列话的时候跳过几个instance variable(有点像java的@transient)

    def __getstate__(self):
        self_dict = self.__dict__.copy()
        # pool object cannot be passed
        del self_dict['callback_tread_pool']

        # weakref object cannot be pickled
        del self_dict['process_mgr']

        # RLock Objects
        del self_dict['pulling_lock']
        del self_dict['server_list_lock']
        return self_dict

    def __setstate__(self, state):
        self.__dict__.update(state)

等我弄清楚了就写一个PR

Felix1029 commented 1 year ago

你应该也是用的也是非Windows系统吧?这个问题是由几个不可序列化的对象导致的。 一个quick patch可以这样,给nacos-sdk-python的client.py增加下列方法,在序列话的时候跳过几个instance variable(有点像java的@transient)

    def __getstate__(self):
        self_dict = self.__dict__.copy()
        # pool object cannot be passed
        del self_dict['callback_tread_pool']

        # weakref object cannot be pickled
        del self_dict['process_mgr']

        # RLock Objects
        del self_dict['pulling_lock']
        del self_dict['server_list_lock']
        return self_dict

    def __setstate__(self, state):
        self.__dict__.update(state)

等我弄清楚了就写一个PR

mac 上的。 不过我看,nacos 2.1.2 的open api 没有监听的内容了,是不是新的版本,不需要监听了?

runzhi214 commented 1 year ago

看官方文档的意思是,这个方法在1.X中存在,由于2.X兼容1.X所以还存在。

我用的nacos2.2.0 BETA. 仍然有这个方法,实现我方法我也写在PR#125里了。

至于是否在未来的版本考虑放弃兼容1.X,彻底移出这个方法不得而知。