Forums

Not able to listen on a port on scheduled task

I see that threads are not allowed in the web application but they are allowed in the scheduled task.

In that case, I created a scheduled task and made it to listen on port 12345 using sockets using rpyc as shown on this page... https://stackoverflow.com/questions/19608781/how-to-interact-with-running-python-script

However, scheduled task is not listening on that port and im getting connection refused error. While this is working all well on my local machine.

Help please!

Hi, that's because your scheduled task may not be running on the same machine as your webapp. You will probably have to say use a database to communicate between them.

I want it real time communication. So I am afraid database solution wont work. rpyc allows socket communication across multiple machines over sockets. Can we have the address of the machine running scheduled tasks and communicate with it?

You can use the ipify api to get your own IP. However, know that this is subject to change on our end without any notice.

Thank you. I can communicate the ip through database.

Now I have a different problem. I am able to find the service and run it through python on my ssh shell. However, when the same code runs as the web application that line conn = rpyc.connect('34.224.65.171', 12345) times out!

What to do?

are you sure your server code was running at the time you tried to talk to it from your web app? Looking at your scheduled task logs, it seems to only run for about 4 seconds.

Check this page for some tips on "long-running'" tasks: http://help.pythonanywhere.com/pages/LongRunningTasks

Hi, I have already implemented that tip. If you check my running processes list you can see server.py running. That process exited in 4 seconds because it was already running.

Apologies, I missed that.

You said your solution works when you try to connect to it from an SSH process. Just to rule things out, does it work when you try from a Bash console? What about from another scheduled task?

It works when I run it from bash but it doesn't work when i run it from another scheduled task. Here is the traceback...

Traceback (most recent call last):
   File "/home/peopleanywhere/mysite/tesr.py", line 70, in search
     conn = rpyc.connect(iP, 12345, config={"allow_all_attrs": True})
   File "/home/peopleanywhere/.local/lib/python2.7/site-packages/rpyc/utils/factory.py", line 90, in connect
     s = SocketStream.connect(host, port, ipv6 = ipv6, keepalive = keepalive)
   File "/home/peopleanywhere/.local/lib/python2.7/site-packages/rpyc/core/stream.py", line 150, in connect
     return cls(cls._connect(host, port, **kwargs))
   File "/home/peopleanywhere/.local/lib/python2.7/site-packages/rpyc/core/stream.py", line 108, in _connect
     s.connect(sockaddr)
   File "/usr/lib/python2.7/socket.py", line 224, in meth
     return getattr(self._sock,name)(*args)
 timeout: timed out

Could it be that your server only supports one connection at a time?

I don't think RPYC has any such restriction. It's a threaded server. How many threads am I allowed? I have a Hacker account right now. Could it be the number of threads exceeding?

re: threads, I doubt it, the limit is 128, and you'd expect to see errors in the rpyc server's logs...

let's rule out the "single connection" hypothesis -- can you connect to it from two different bash consoles, simultaneously?

next, just to double-check, are you sure that the code you're running from bash is exactly the same as the code from a scheduled task?

Yes I can connect it from two different bash consoles simultaneously.

And yes I am sure that the code I am running from bash is exactly same as the code from the scheduled task.

Here is the function I am using in all the cases.

def check():
    _w = "candy"
    _cont = ""
    try:
        _w = request.args.get('w')
    except:
        pass
    try:
        conn = rpyc.connect('34.224.65.171', 12345, config={"allow_all_attrs": True})
        c = conn.root
        time.sleep(5)
        result = c.check(_w)
        return result
    except:
        return traceback.format_exc()

OK let's try and get a minimal repro together. Can you create an absolutely minimal rpyc server, I'm thinking 4 or 5 lines of code, that just does something really simple like ping-pong or responds with an ok to everything? and some client code to call it?

share that here and we can try running it ourselves, to see if we can repro the problem..

This page has that minimal example here... I just barely changed the ip... https://stackoverflow.com/questions/19608781/how-to-interact-with-running-python-script

It looks like you're right - the connection does work from a console, but not from a scheduled task. We'll have to do a bit more investigation to work out why that might be the case.

OK. Some investigation has revealed that the console server is a special case - it works because there are specific network rules allowing the traffic. There is a way to work round that by using the local ip address of the machine where the server is running. You can get it with this code:

import socket
def get_ip_address():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    return s.getsockname()[0]

You will need to use the above code to get the ip of the server (run it when the server starts up) Then you will need to put the ip address that is returned into a file somewhere so your client can read it and use it, since it may change between runs of your server.