How to make synchronous rpc calls

I am creating a program that has a class used locally, but I want the same class to be used in the same way over the network. This means that I need to be able to make synchronous calls to any of my public methods. The class reads and writes files, so I think XML-RPC is way too expensive. I created a basic rpc client / server using twisted examples, but I am having problems with the client.

c = ClientCreator(reactor, Greeter) c.connectTCP(self.host, self.port).addCallback(request) reactor.run() 

This works for a single call, when the data is received, I call operator.stop (), but if I make more calls, the reactor will not restart. Is there anything else I should use for this? maybe another twisted module or another structure?

(I do not include details about how the protocol works, because the main thing is that I get only one call from this.)

Addition and clarification:

I shared a google document with notes on what I am doing. http://docs.google.com/Doc?id=ddv9rsfd_37ftshgpgz

I have a written version that uses a fuse and can combine several local folders at the point of connection of the fuse. File access is already being processed inside the class, so I want to have servers that give me access to the network for one class. After continuing the search, I suspect that pyro ( http://pyro.sourceforge.net/ ) may be what I'm really looking for (just based on reading their homepage right now), but I'm open to any suggestions.

I could achieve similar results using mount nfs and combining it with my local folder, but I want all peers to have access to the same federated file system, so that every computer had to sing an nfs server with the number of mounts nfs is equal to the number of computers on the network.

Conclusion: I decided to use rpyc as it gave me exactly what I was looking for. A server that stores an instance of a class that I can manipulate as if it were local. If anyone is interested, I posted my project on Launchpad ( http://launchpad.net/dstorage ).

+4
source share
4 answers

If you're even considering Pyro, check out RPyC first and rethink XML-RPC.

As for Twisted: try leaving the reactor, not stopping it, and just ClientCreator(...).connectTCP(...) every time.

If you self.transport.loseConnection() in your protocol, you will not leave open connections.

+2
source

Why do you feel it should be synchronous?

If you want only one of them to be executed at a time, call all calls through DeferredSemaphore so that you can limit the actual calls (to any arbitrary value).

If you want to be able to start several threads from them at different times, but do not care about concurrency restrictions, then you should at least separate the start-up and disconnection of the reactor from calls (the reactor must work for the entire lifetime of the process).

If you just can't figure out how to express your application logic in a reactor template, you can use deferToThread and write a piece of purely synchronous code, although I would suggest that it is not needed.

+2
source

For a synchronized client, Twisted is probably not a suitable option. Instead, you can use the socket module directly.

 import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((self.host, self.port)) s.send(output) data = s.recv(size) s.close() 

The recv() call may need to be repeated until you get an empty string, but this shows the basics.

Alternatively, you can change your entire program to support asynchronous calls ...

+1
source

If you are using Twisted, you should probably know that:

  • You will not make synchronous calls in any network service.
  • The reactor can only be started once, so do not stop it (by calling reactor.stop() ) until your application is ready to exit.

Hope this answers your question. I personally believe that Twisted is exactly the right solution for your use case, but you need to solve the synchronization problem.

Addition and clarification:

Part of what I don't understand is that when I call the .run () reactor, it seems to go into a loop that is just hours for network activity. How do I continue to execute the rest of mine while it uses the network? if I can get past this, then I can probably have a synchronization problem.

This is exactly what the .run () reactor does. It controls the main circuit, which is an event reactor. He will not only wait for events related to work, but also everything that you have planned. With Twisted, you will need to structure the rest of your application to deal with its asynchronous nature. Perhaps if we knew what this application is, we could advise.

+1
source

All Articles