tomerfiliba-org / rpyc

RPyC (Remote Python Call) - A transparent and symmetric RPC library for python
http://rpyc.readthedocs.org
Other
1.57k stars 243 forks source link

Server aborts when interfacing with cdll using ctypes #532

Open Sathisha-Movvar-Bose opened 1 year ago

Sathisha-Movvar-Bose commented 1 year ago

I have a c_dll_wrapper class implemented using ctypes which I want to expose via a RpycService. But if I instantiate this C_dll_Wrapper instance in the service class the ThreadedServer aborts as soon as the client makes a call to the function that creates the object of c_dll_wrapper. If I skipe this step everything works fine. any reason?

# Below code is when the CDLL_wrapper class was not instantiated; client didn't call server.simulate method

(OJ) C:\asd\CART\BVP\src\Model>python -m bvp_BAF
on_connect (<rpyc.core.protocol.Connection 'conn1' object at 0x0000019805A87190>,)
Rpyc's process_clock_tick
on_disconnect (<rpyc.core.protocol.Connection 'conn1' object at 0x0000019805A87190>,)
on_connect (<rpyc.core.protocol.Connection 'conn2' object at 0x0000019805A94750>,)
Rpyc's process_clock_tick
on_disconnect (<rpyc.core.protocol.Connection 'conn2' object at 0x0000019805A94750>,)
on_connect (<rpyc.core.protocol.Connection 'conn3' object at 0x0000019805A94ED0>,)
Rpyc's process_clock_tick
on_disconnect (<rpyc.core.protocol.Connection 'conn3' object at 0x0000019805A94ED0>,)

# below code with server.simulate called.
(OJ) C:\asd\CART\BVP\src\Model>python -m bvp_BAF
on_connect (<rpyc.core.protocol.Connection 'conn1' object at 0x000001F6A16B3850>,)
<class 'ctypes.c_long'>;         memory_size = 0x24A0
<class 'ctypes.c_void_p'>;       memory_pointer = 0x1F6A16C1118    
<class 'ctypes.c_long'>;         memory_log_size = 0xFA0
<class 'ctypes.c_void_p'>;       memory_log_pointer = 0x1F6A16C1198
<class 'ctypes.c_long'>;         print_log_size = 0x0
<class 'ctypes.c_long'>;         capture_log_size = 0x0
<class 'ctypes.c_long'>;         exec_log_size = 0x0
<class 'ctypes.c_long'>;         num_threads = 0x2
<class 'ctypes.c_long'>;         call_interval = 0x0
<class 'ctypes.c_long'>;         base_thread = 0x0
<class 'ctypes.c_long'>;         ext_scheduler = 0x0

Rpyc's process_clock_tick

(OJ) C:\asd\CART\BVP\src\Model> # see the server aborted for some reason.
Environment
Minimal example

Server:

class RpycService(rpyc.Service):
    def __init__(self):
        self._root_cart_wrapper = None

    def on_connect(self, *args):
        print ("on_connect", args)

    def on_disconnect(self, *args):
        print ("on_disconnect", args)

    def exposed_simulate(self, cdll_path=""):
        self._root_cart_wrapper = sims.BAF_SIL_Sync(cdll_path)

    def exposed_process_clock_tick(self, *args, **kwargs):
        #self._root_cart_wrapper.process_clock_tick(*args, **kwargs)
        print ("Rpyc's process_clock_tick")

def _lauch_service():
    _log.info("Starting BAF service...")
    from rpyc.utils.server import ThreadedServer

    rpyc_config = {"allow_public_attrs":True, "allow_all_attrs":False, "allow_getattr":True, "allow_setattr":False, "allow_pickle":True}
    service = ThreadedServer(RpycService(), port=0xB05E+31)#, protocol_config=rpyc_config)
    _log.critical("BAF Service running")
    service.start()
    _log.critical("BAF Service stopping...")
    service.close()

Client:

import rpyc

class BAF_Client():
    def __init__(self, ip_address:str="localhost", port_num:int=0xB05E+31):
            rpyc_config = {"allow_public_attrs":True, "allow_all_attrs":False, "allow_getattr":True, "allow_setattr":False, "allow_pickle":True}
            self._rpyc_connection = rpyc.connect(ip_address, port_num)#, config=rpyc_config)
            self._rpyc_connection._config['sync_request_timeout'] = 10 # sec
            self._sim_handle = self._rpyc_connection.root

    def __del__(self):
        self.disconnect()

    def disconnect(self):
        if (self._rpyc_connection is not None):
            self._rpyc_connection.close()
            self._rpyc_connection = None
            self._sim_handle = None

  baf1_dll = r"C:\asd\CART\src_svn\cart_trunk\Baf1.dll"
  #baf2_dll = r"C:\asd\CART\src_svn\cart_trunk\Baf2.dll"
  # test_baf_sil(baf1_dll)
  baf1=BAF_Client()
  #baf1._sim_handle.simulate(baf1_dll)
  baf1._sim_handle.process_clock_tick()
  del(baf1)
Sathisha-Movvar-Bose commented 1 year ago

Sorry changing the server to ThreadPoolServer seems to get it working.