RpcProxy inside method

78 views
Skip to first unread message

juko...@gmail.com

unread,
Oct 17, 2017, 6:08:07 PM10/17/17
to nameko-dev
Hi,

I have a collection of sub-services that I want to spawn from a master service, they all share a common prefix in the method name. For example `import-a`, `import-b`, etc

So I was thinking something along the lines of instantiating the RpcProxy instance at runtime, inside the master service method. But I can't figure out the 'right' way to do it.

So for example (and I know this won't work):

```
from nameko.rpc import rpc, RpcProxy

class Importer:
    name = "import"

    @rpc
    def run(self, servicename, value):
        r = RpcProxy('{}-{}'.format(self.name, servicename))
        return r.run(value)


class ImportA:
    name = "import-a"

    @rpc
    def run(self, value):
        return '{} ran with {}'.format(self.name, value)


class ImportB:
    name = "import-b"

    @rpc
    def run(self, value):
        return '{} ran with {}'.format(self.name, value)


```

Then later, I could write and start an `import-c` service, and nothing else needs to change.

Any thoughts?

Geoff

Chebli, Manfred

unread,
Oct 18, 2017, 3:17:37 AM10/18/17
to juko...@gmail.com, nameko-dev
We have more or less the same problematic, and we solved it with an extension that spawn ServiceProxy.

Here's a snippet

```
from nameko.extensions import DependencyProvider
from nameko.rpc import ServiceProxy, ReplyListener


class RpcProxyFactory(object):

    def __init__(self, worker_ctx, reply_listener):
        self.worker_ctx = worker_ctx
        self.reply_listener = reply_listener

    def __call__(self, target_service):
        return ServiceProxy(self.worker_ctx, target_service, self.reply_listener)


class DynamicRpcProxy(DependencyProvider):
    rpc_reply_listener = ReplyListener()

    def get_dependency(self, worker_ctx):
return RpcProxyFactory(worker_ctx, self.rpc_reply_listener)


class Service(object):
    dynamic_rpc_proxy = DynamicRpcProxy()

    def run(self, value):
        sub_service_a = dynamic_rpc_proxy("sub_service_a")
        sub_service_a.run("hello")  # returns "sub_service_a-hello"

class SubServiceA(object):
    name = "sub_service_a"

    def run(self, value):
        return "{}-{}".format(self.name, value)
```

Hope this helps.
Also, I'm not too sure what I'm doing here. Therefore, any comment on this snippet is most welcome.


Manfred

--
You received this message because you are subscribed to the Google Groups "nameko-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nameko-dev+unsubscribe@googlegroups.com.
To post to this group, send email to namek...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/nameko-dev/407ee317-fbbf-41ce-b619-b67d062a64e4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
 Manfred Chebli
 Ingénieur Logiciel


 04 78 18 75 38 | manfred...@forcity.io
 
     

Matt Yule-Bennett

unread,
Oct 19, 2017, 8:02:47 PM10/19/17
to nameko-dev
This is pretty much the simplest implementation of a "dynamic RPC proxy" possible, because it reuses so much of the built-in extension. I think it's a neat way to solve exactly the problem Geoff describes.
Message has been deleted

juko...@gmail.com

unread,
Oct 23, 2017, 12:11:49 PM10/23/17
to nameko-dev
Thanks Manfred! This is extremely useful
To unsubscribe from this group and stop receiving emails from it, send an email to nameko-dev+...@googlegroups.com.

To post to this group, send email to namek...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/nameko-dev/407ee317-fbbf-41ce-b619-b67d062a64e4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

juko...@gmail.com

unread,
Nov 7, 2017, 2:43:53 PM11/7/17
to nameko-dev
I thought I'd follow up on myself here.

Manfred's solution worked well for me. But I didn't run with it.

After further thought, I realized that I could achieve the same result far more effectively using the Events system. So rather than sending a task to a specific process, I publish the task in a way that includes details on 'who' should run it. Then all the interested processes receive and act accordingly. This gave me what I ultimately required, which is the ability to add more services that could act upon the task.

I'm finding (quite often) that if I can't do something obviously in Nameko, I'm probably thinking about it wrong :)

Awesome!
Reply all
Reply to author
Forward
0 new messages