user1939565
user1939565

Reputation: 203

Restart Python.py when it stops working

I am using Cherrypy framework to run my python code on server. But the process stops working when the load increases.

Every time this happens I have to manually go and start the python code. Is there any way i can use Gunicorn with Cherrypy so that Gunicorn can start the code automatically when it stops working.

Any other solution will also work in this case. Just want to make sure that the python program does not stop working.

Upvotes: 1

Views: 2035

Answers (4)

Marc Maxmeister
Marc Maxmeister

Reputation: 4689

I use a cron that checks the memory load every few minutes and resets cherrypy when the memory exceeds 500MB -- so that the web host doesn't complain to me with emails. Something on my server doesn't release memory when a function ends as it should, so this is a pragmatic work around.

This hack may be weird because I reset it using an HTTP request, but that's because I spent hours trying to figure out how to do this withing the BASH and gave up. It works.

CRON PART

*/2 * * * * /usr/local/bin/python2.7 /home/{mypath}/cron_reset_cp.py > $HOME/cron.log 2>&1

And code inside cron_reset_cp.py...

#cron for resetting cherrypy /cp/ when 500+ MB
import os
#assuming starts in /home/my_username/
os.chdir('/home/my_username/cp/')
import mem
C = mem.MemoryMonitor('my_username') #this function adds up all the memory
memory = int(float(C.usage()))
if memory > 500:#MB
    #### Tried: pid = os.getpid() #current process = cronjob --- THIS approach did not work for me.
    import urllib2
    cp = urllib2.urlopen('http://myserver.com/cp?reset={password}')

Then I added this function to reset the cherrypy via cron OR after a github update from any browser (assuming only I know the {password})

The reset url would be http://myserver.com/cp?reset={password}

def index(self, **kw):
    if kw.get('reset') == '{password}': 
        cherrypy.engine.restart()
        ip = cherrypy.request.headers["X-Forwarded-For"] #get_client_ip
        return 'CherryPy RESETTING for duty, sir! requested by '+str(ip)

The MemoryMonitor part is from here: How to get current CPU and RAM usage in Python?

Upvotes: 1

Marek Wywiał
Marek Wywiał

Reputation: 39

Perhaps you need supervisord to monitor your gunicorn process and restart it when it's necessary:

Upvotes: 0

Torxed
Torxed

Reputation: 23490

Depending on your OS, try the following logic:

  1. Implement a os.pid() > /path/pid.file
  2. Create a service script that connected to your web-port
  3. Try to fetch data
  4. If no data was recieved, kill PID @/path/pid.file
  5. restart script

Your main script:

import os
with open('./pidfile.pid', 'wb') as fh:
    fh.write(str(os.getpid()))

... Execute your code as per normal ...

service.py script:

from socket import *
from os import kill
s = socket()
try:
    s.connect(('127.0.0.1', 80))
    s.send('GET / HTTP/1.1\r\n\r\n')
    len = len(s.recv(8192))
    s.close()
except:
    len = 0
if len <= 0:
    with open('/path/to/pidfile.pid', 'rb') as fh:
        kill(int(fh.read()))

And have a cronjob (execute in a console):

sudo export EDITOR=nano; crontab -e

Now you're in the text-editor editing your cronjobs, write the following two lines at the bottom:

*/2 * * * * cd /path/to/service.py; python service.py
*/5 * * * * cd /path/to/main/script.py; python script.py

Press Ctrl+X and when asked to save changes, write Y and enjoy.

Also, instead of restarting your script from within service.py script, i'd suggest that service.py kills the PID located in /path/pid.file and let your OS handle starting up your script if the PID is missing in /path/, Linux at least have very nifty features for this.

Best practice Ubuntu

It's more than considered best practice to use the systems service status apache2 for instance, the service scripts lets you reload, stop, start, get job states and what not.

Check out: http://upstart.ubuntu.com/cookbook/#service-job And check the service scripts for all the other applications and not only use them as skeletons but make sure your application follows the same logic.

Upvotes: 0

Kai Kuspa
Kai Kuspa

Reputation: 25

Python uses many error handling strategies to control flow. A simple try/except statement could throw an exception if, say, your memory overflowed, a load increased, or any number of issues making your code stall (hard to see without the actual code).

In the except clause, you could clear any memory you allocated and restart your processes again.

Upvotes: 1

Related Questions