Search code examples
pythonapiraspberry-pigunicornfalconframework

falcon api using gunicorn WORKER TIMEOUT Raspberry Pi


import falcon
global_var=False

class set_gv(object):
    def on_get(self, req, res):
        """Handles all GET requests."""
        res.status = falcon.HTTP_200  # This is the default status
        global global_var
        global_var=not global_var
        res.body = (str(global_var))

class ask_gv(object):
    def on_get(self, req, res):
        """Handles all GET requests."""
        res.status = falcon.HTTP_200  # This is the default status
        res.body = str(global_var)

# Create the Falcon application object
app = falcon.API()

# Instantiate the TestResource class
set = set_gv()
get = ask_gv()

# Add a route to serve the resource
app.add_route('/set', set)
app.add_route('/get', get)

I am using Falcon framework with gunicorn and above code to host an API to hold a variable and change and retrieve it using API calls with command

`gunicorn -b 0.0.0.0:5000 main:app --reload` 

When I open http://localhost/set it correctly changes and return the value but after sometime I get following error on console and the varaible value is reset

[CRITICAL] WORKER TIMEOUT (pid:8545)

Any help on how to fix that. Thanks in advance.


Solution

  • So I figure out that worker process is still timeout and restart after some time but I was able to solve the issue with following:

    Instead of defining a global variable which gets reset after every timeout I used pickle module to save variable value on disk and change it and read it with every set and get call respectively.

    import pickle
    f = open('store.pckl', 'wb')
    pickle.dump(False, f)
    f.close()
    
    class set_gv(object):
        def on_get(self, req, res):
            """Handles all GET requests."""
            res.status = falcon.HTTP_200  # This is the default status
            f = open('store.pckl', 'rb')
            obj = not pickle.load(f)
            f.close()
            f = open('store.pckl', 'wb')
            pickle.dump(obj, f)
            f.close()
            res.body = (str(obj))
    
    class ask_gv(object):
        def on_get(self, req, res):
            """Handles all GET requests."""
            res.status = falcon.HTTP_200  # This is the default status
            f = open('store.pckl', 'rb')
            obj = pickle.load(f)
            f.close()
            res.body = (str(obj))
    

    I added 3 workers to ensure uptime.

    gunicorn -b 0.0.0.0:5000 main:app --reload --workers=3

    Update: I was able to solve the worker timeout issue, I was running the api server on a Raspberry Pi and the input voltage to it was a little bit less than optimal and was causing the worker timeout issue. Fixing the voltage fixed the issue.