nameko / nameko-amqp-retry

Other
24 stars 4 forks source link

Wrong providers when using a mix of retriable rpcs and normal rpcs #32

Open AndreGraca98 opened 1 year ago

AndreGraca98 commented 1 year ago

Hello, I'm working on a project that uses both normal rpcs nameko.rpc.rpc and retryable rpcs nameko_amqp_retry.rpc.rpc

What I expected: I expected to be able to call either type of rpcs without an order.

What happens: If i call the methods in a way like normal rpc, retyable rpc, normal rpc, retyable rpc (...) it works fine, but if I change the order or always try to call the same it errors out every other time with MethodNotFound

Why: This cause an issue where the providers change every time there is an rpc call. I tracked down the issue to it being due to class variables. In the file nameko_amqp_retry/rpc.py the class RPC creates the consumer again as a class variable. This makes the self._providers have different values for normal rpcs and retyable rpcs.

Where does it happen: nameko_amqp_retry/rpc.py

from nameko.rpc import RpcConsumer as NamekoRpcConsumer

class RpcConsumer(NamekoRpcConsumer):
    ...

class Rpc(NamekoRpc):

    rpc_consumer = RpcConsumer()
    # rpc_consumer = NamekoRpcConsumer() # If we use this or if we compelitly remove 
    # the rpc_consumer it works fine
    backoff_publisher = BackoffPublisher()

Example:

Service in service_test.py

from nameko.rpc import rpc as rpc_nameko
from nameko_amqp_retry.rpc import rpc as rpc_nameko_ampq_retry

print("Running service_test.py")

class Service:
    name = "service_test"

    @rpc_nameko
    def rpc_from_nameko(self):
        print("rpc_from_nameko\n")

    @rpc_nameko_ampq_retry
    def rpc_from_nameko_ampq_retry(self):
        print("rpc_from_nameko_ampq_retry\n")

In console 1:

nameko run "service_test:Service"

In console 2:

pipenv run nameko shell
>>> n.rpc.service_test.rpc_from_nameko() # Runs fine
>>> n.rpc.service_test.rpc_from_nameko() # Errors out
nameko.exceptions.MethodNotFound: rpc_from_nameko
>>> n.rpc.service_test.rpc_from_nameko() # Runs fine again
...
And so on