trhr
trhr

Reputation: 148

Django - Render HTTP before database connection

I have a serverless database cluster that spins down when it's out of use. Cold starts take a minute or so, during which django just waits and waits to send the http request object back.

Before I code something complicated, I'm looking for recommendations for an existing middleware/signal integration that would allow me to render an interim view while django attempts to get the database connection (for instance, if the database query takes longer than a second to complete, render to this view instead.)

Upvotes: 0

Views: 205

Answers (2)

trhr
trhr

Reputation: 148

Partial solution:

  • I reduced the RESTful gateway's query timeout to 3 seconds. At the end of timeout, I return a 504 Error with a nice message that tells the user that the server has gone to sleep but it will be booting back up shortly. Inside the text/html response of the 504 Error, I included a refresh meta tag, so browsers will automatically try to reload the view.

  • I took all database calls off the public-facing site and put them behind an authentication layer. This means that authenticating will be the step most likely to time out, and users will (I hope) naturally try to reauthenticate after receiving the 504 Error above.

  • I added an AJAX jquery call in document.ready() to pull a random database record. This query will time out and nothing will happen (as intended). It forces the database server to begin booting up immediately whenever a user hits a public-facing page.

Upvotes: 0

Iain Shelvington
Iain Shelvington

Reputation: 32294

You could create a custom middleware that tests for DB connectivity on every request. Bear in mind that this will attempt to create a new DB connection on every request

from django.db import connection
from django.db.utils import OperationalError
from django.shortcuts import render_to_response

def db_is_up_middleware(get_response):

    def middleware(request):
        try:
            c = connection.cursor()
        except OperationalError:
            return render_to_response('your_template.html')
        else:
            return get_response(request)

    return middleware

Upvotes: 2

Related Questions