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

Cannot proxy requests? #294

Open
Zentren opened this issue Jul 12, 2022 · 0 comments
Open

Cannot proxy requests? #294

Zentren opened this issue Jul 12, 2022 · 0 comments

Comments

@Zentren
Copy link

Zentren commented Jul 12, 2022

Is it not possible to proxy-chain requests returning (at least) struct responses?

i.e. client <=> proxy.rpc() <=> server.rpc()

Please see attached test code to better understand issue and reproduce. Commented-out lines from line 22 can be uncommented separately to investigate (not-so-different) outcomes. Either an exception is raised, or default values for fields are returned.

Test code

test.py

from unittest import result
import capnp
import socket

import test_capnp


class Test(test_capnp.Test.Server):

    def getResult(self, **kwargs):
        return test_capnp.Result.new_message(value=1)


class TestProxy(test_capnp.Test.Server):

    def __init__(self, test):
        self._test = test

    def getResult(self, **kwargs):
        return self._test.getResult()  # remote exception: <class 'AttributeError'>:'NoneType' object has no attribute 'type'

        # return self._test.getResult().result  # remote exception: <class 'AttributeError'>:'NoneType' object has no attribute 'type'

        # return self._test.getResult().then(lambda response: {"value": 1})
        
        # return self._test.getResult().then(
        #     lambda _: test_capnp.Result.new_message(value=1),
        #     error_func=lambda error: print(error),
        # )

        # return self._test.getResult().then(
        #     lambda response: self._copy_response_result(response),
        #     error_func=lambda error: print(error),
        # )

        # return self._test.getResult().then(
        #     lambda response: self._copy_response_result_as_builder(response),
        #     error_func=lambda error: print(error),
        # )

        # return self._test.getResult().then(
        #     lambda response: self._reuse_response(response),
        #     error_func=lambda error: print(error),
        # )

    def _reuse_response(self, response):
        print("Server result value: " + str(response.result.value))
        return response

    def _copy_response_result(self, response):
        print("Server result value: " + str(response.result.value))
        return test_capnp.Result.new_message(value=response.result.value)

    def _copy_response_result_as_builder(self, response):
        print("Server result value: " + str(response.result.value))
        return response.result.as_builder()


def test():
    principal_server_sock, principal_client_sock = socket.socketpair(socket.AF_UNIX)

    principal_server = capnp.TwoPartyServer(principal_server_sock, bootstrap=Test())
    principal_client = capnp.TwoPartyClient(principal_client_sock)

    proxy_server_sock, proxy_client_sock = socket.socketpair(socket.AF_UNIX)

    proxy = TestProxy(principal_client.bootstrap().cast_as(test_capnp.Test))
    proxy_server = capnp.TwoPartyServer(proxy_server_sock, bootstrap=proxy)
    proxy_client = capnp.TwoPartyClient(proxy_client_sock)

    test_client = proxy_client.bootstrap().cast_as(test_capnp.Test)
    
    result = test_client.getResult().wait().result

    print("Proxy result: " + str(result))
    assert result.value == 1


if __name__ == "__main__":
    test()

test.capnp

@0xc5358bd118c9ee3a;

struct Result {
    value @0 :Int32;
}

interface Test {
    getResult @0 () -> (result :Result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant