Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using rpyc over rpyc throws an exception #346

Closed
eyalgr opened this issue Aug 21, 2019 · 3 comments
Closed

using rpyc over rpyc throws an exception #346

eyalgr opened this issue Aug 21, 2019 · 3 comments
Assignees
Labels
Done The issue discussion is exhausted and is closed w/ comment

Comments

@eyalgr
Copy link

eyalgr commented Aug 21, 2019

I have a use case where I have a frontend server in a public-facing network and a bunch
of backend servers in an isolated network that's accessible from the frontend server.

I considered using rpyc to handle this case. In order to simulate this I started two classic services on localhost:

# Frontend server:
python /usr/local/bin/rpyc_classic.py -p 8080
# Backend server:
python /usr/local/bin/rpyc_classic.py -p 8081

And attempted to use rpyc over rpyc:

>>> import rpyc
>>> frontend = rpyc.connect('localhost', 8080)
>>> frontend_rpyc = frontend.root.getmodule('rpyc')
>>> backend = frontend_rpyc.connect('localhost', 8081)
>>> backend.root.getmodule('os').listdir('.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 161, in __getattribute__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 76, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 100, in value
    self.wait()
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 47, in wait
    self._conn.serve(self._ttl)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 387, in serve
    self._dispatch(data)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 353, in _dispatch
    self._dispatch_request(seq, args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 337, in _dispatch_request
    self._send(consts.MSG_REPLY, seq, self._box(res))
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 259, in _send
    self._channel.send(data)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/channel.py", line 75, in send
    self.stream.write(buf)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/stream.py", line 267, in write
    count = self.sock.send(data[:self.MAX_IO_CHUNK])
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/stream.py", line 94, in __getattr__
    raise EOFError("stream has been closed")
EOFError: stream has been closed

I should note that connecting directly to the backend works as expected, but it doesn't solve this specific use case.
I'm new to rpyc, so I'm not sure if it's even supposed to work this way.

This is the log from the frontend server:

> python /usr/local/bin/rpyc_classic.py -p 8080
INFO:SLAVE/8080:server started on [127.0.0.1]:8080
INFO:SLAVE/8080:accepted ('127.0.0.1', 62811) with fd 4
INFO:SLAVE/8080:welcome ('127.0.0.1', 62811)
INFO:SLAVE/8080:goodbye ('127.0.0.1', 62811)
ERROR:SLAVE/8080:client connection terminated abruptly
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 180, in _authenticate_and_serve_client
    self._serve_client(sock2, credentials)
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 202, in _serve_client
    self._handle_connection(conn)
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 208, in _handle_connection
    conn.serve_all()
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 403, in serve_all
    self.serve(None)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 387, in serve
    self._dispatch(data)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 353, in _dispatch
    self._dispatch_request(seq, args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 337, in _dispatch_request
    self._send(consts.MSG_REPLY, seq, self._box(res))
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 273, in _box
    id_pack = get_id_pack(obj)
  File "/usr/local/lib/python3.7/site-packages/rpyc/lib/__init__.py", line 159, in get_id_pack
    name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 166, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 76, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 102, in value
    raise self._obj
_get_exception_class.<locals>.Derived: 'SlaveService' object has no attribute '__name__'

========= Remote Traceback (1) =========
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 589, in _handle_getattr
    return self._access_attr(obj, name, (), "_rpyc_getattr", "allow_getattr", getattr)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 523, in _access_attr
    return accessor(obj, name, *args)
AttributeError: 'SlaveService' object has no attribute '__name__'

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 180, in _authenticate_and_serve_client
    self._serve_client(sock2, credentials)
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 202, in _serve_client
    self._handle_connection(conn)
  File "/usr/local/lib/python3.7/site-packages/rpyc/utils/server.py", line 208, in _handle_connection
    conn.serve_all()
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 403, in serve_all
    self.serve(None)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 387, in serve
    self._dispatch(data)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 353, in _dispatch
    self._dispatch_request(seq, args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 337, in _dispatch_request
    self._send(consts.MSG_REPLY, seq, self._box(res))
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 273, in _box
    id_pack = get_id_pack(obj)
  File "/usr/local/lib/python3.7/site-packages/rpyc/lib/__init__.py", line 159, in get_id_pack
    name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 166, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 76, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 102, in value
    raise self._obj
_get_exception_class.<locals>.Derived: 'SlaveService' object has no attribute '__name__'

========= Remote Traceback (1) =========
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 589, in _handle_getattr
    return self._access_attr(obj, name, (), "_rpyc_getattr", "allow_getattr", getattr)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 523, in _access_attr
    return accessor(obj, name, *args)
AttributeError: 'SlaveService' object has no attribute '__name__'

And this is the log from the backend server:

> python /usr/local/bin/rpyc_classic.py -p 8081
INFO:SLAVE/8081:server started on [127.0.0.1]:8081
INFO:SLAVE/8081:accepted ('127.0.0.1', 62812) with fd 4
INFO:SLAVE/8081:welcome ('127.0.0.1', 62812)
DEBUG:SLAVE/8081:Exception caught
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 589, in _handle_getattr
    return self._access_attr(obj, name, (), "_rpyc_getattr", "allow_getattr", getattr)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 523, in _access_attr
    return accessor(obj, name, *args)
AttributeError: 'SlaveService' object has no attribute '__name__'
DEBUG:SLAVE/8081:Exception caught
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 589, in _handle_getattr
    return self._access_attr(obj, name, (), "_rpyc_getattr", "allow_getattr", getattr)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 523, in _access_attr
    return accessor(obj, name, *args)
AttributeError: 'SlaveService' object has no attribute '__name__'
@comrumino comrumino self-assigned this Aug 22, 2019
@comrumino comrumino added To Start Description reviewed and a maintainer needs "to start" triage Done The issue discussion is exhausted and is closed w/ comment and removed To Start Description reviewed and a maintainer needs "to start" triage labels Aug 22, 2019
@comrumino
Copy link
Collaborator

Thanks for reporting the issue!

@eyalgr
Copy link
Author

eyalgr commented Aug 22, 2019

Thank you for the quick reply!

It did solve the issue, but unfortunately now doing the same as above throws another exception:

>>> backend = frontend_rpyc.connect('localhost', 8081)
>>> backend.root
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 166, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 76, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 100, in value
    self.wait()
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 47, in wait
    self._conn.serve(self._ttl)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 387, in serve
    self._dispatch(data)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 355, in _dispatch
    obj = self._unbox(args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 301, in _unbox
    proxy = self._netref_factory(id_pack)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 314, in _netref_factory
    cls_methods = self.sync_request(consts.HANDLE_INSPECT, id_pack)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 102, in value
    raise self._obj
AttributeError: 'SlaveService' object has no attribute '__mro__'

========= Remote Traceback (2) =========
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 586, in _handle_inspect
    return tuple(get_methods(netref.LOCAL_ATTRS, self._local_objects[id_pack]))
  File "/usr/local/lib/python3.7/site-packages/rpyc/lib/__init__.py", line 179, in get_methods
    mros = list(reversed(type(obj).__mro__)) + list(reversed(obj.__mro__))
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 166, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/netref.py", line 76, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 458, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/async_.py", line 102, in value
    raise self._obj
_get_exception_class.<locals>.Derived: 'SlaveService' object has no attribute '__mro__'

========= Remote Traceback (1) =========
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 323, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 589, in _handle_getattr
    return self._access_attr(obj, name, (), "_rpyc_getattr", "allow_getattr", getattr)
  File "/usr/local/lib/python3.7/site-packages/rpyc/core/protocol.py", line 523, in _access_attr
    return accessor(obj, name, *args)
AttributeError: 'SlaveService' object has no attribute '__mro__'

knowikow added a commit to knowikow/rpyc that referenced this issue Sep 13, 2019
comrumino added a commit that referenced this issue Sep 14, 2019
Added a test for RPyC over RPyC (Tests #346)
@comrumino
Copy link
Collaborator

comrumino commented Sep 14, 2019

Must've missed your comment post "fix", I'll take a look at this issue again soon

@comrumino comrumino reopened this Sep 14, 2019
@comrumino comrumino added Triage Investigation by a maintainer has started and removed Done The issue discussion is exhausted and is closed w/ comment labels Sep 14, 2019
@comrumino comrumino added Done The issue discussion is exhausted and is closed w/ comment and removed Triage Investigation by a maintainer has started labels Oct 2, 2019
YuvalEvron pushed a commit to weka/rpyc that referenced this issue Oct 27, 2019
* Added warning to _remote_tb when the major version of local and remote mismatch (tomerfiliba-org#332)

* Added `include_local_version` to DEFAULT_CONFIG to allow for configurable security controls (e.g. `include_local_traceback`)

* Update readme.txt

* Added break to client process loop when everything is dead

* Increased chunk size to improve multi-client response time and throughput of large data tomerfiliba-org#329

* Improved test for response of client 1 while transferring a large amount of data to client 2

* Cleaned up coding style of test_service_pickle.py

* Updated issue template

* added vs code testing cfgs; updated gitignore venv

* Changed settings.json to use env USERNAME

* Name pack casted in _unbox to fix IronPython bug. Fixed tomerfiliba-org#337

* Fixed netref.class_factory id_pack usage per tomerfiliba-org#339 and added test cases

* Added .readthedocs.yml and requirements to build

* Make OneShotServer terminates after client connection ends

* Added unit test for OneShotServer. Fixed tomerfiliba-org#343

* Fixed 2.6 backwards incompatibility for format syntax

* Updated change log and bumped version --- 4.1.1

* Added support for chained connections which result in netref being passed to get_id_pack. Fixed tomerfiliba-org#346

* Added tests for get_id_pack

* Added a test for issue tomerfiliba-org#346

* Corrected the connection used to inspect a netref

* Refactored __cmp__ getattr

* Extended rpyc over rpyc unit testing and removed port parameter from TestRestricted

* Added comment explaining the inspect for intermediate proxy. Fixed tomerfiliba-org#346

* Improved docstring for serve_threaded to address when and when not to use the method. Done tomerfiliba-org#345

* Release 4.1.2

* Fixed versions referred to in security.rst

* link docs instead of mitre

* set up logging with a better formatter

* fix bug when proxy context-manager is being exited with an exception (#1)

* logging: add a rotating file log handler

* fix bug when proxy context-manager is being exited with an exception (#1)

* logging: add a rotating file log handler
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Done The issue discussion is exhausted and is closed w/ comment
Projects
None yet
Development

No branches or pull requests

2 participants