Search code examples
pythondjangopubnubpythonanywhere

Using PubNub to publish message in Django view


I want to use PubNub to publish a message from a Django view. I'm running my web app on pythonanywhere. It seems to work fine at first, but if I refresh the page a few times in succession, I eventually catch a RuntimeError exception with the message "can't start new thread". If I wait a bit (I'm not sure how long), it resumes working again, and then repeats the same behavior.

It seems the issue is with starting a new thread for the callback, but I'm not sure.

Here's the code for my view and callback in views.py:

def my_view(request):
    try:
        pnconfig = PNConfiguration()

        pnconfig.subscribe_key = '<sub key>'
        pnconfig.publish_key = '<pub key>'
        pnconfig.ssl = False

        pubnub = PubNub(pnconfig)
        pubnub.publish().channel('MyDemoChannel').message({"text": "Message from my_view()"}).async(publish_callback)
    except:
        logger.exception("Caught exception in my_view()")

        context = {'val_1': 1, 'val_2': 2}
        return render( request, 'my_app/my_view.html', context)


def publish_callback(envelope, status):
    if not status.is_error():
        pass
    else:
        pass

And the stack trace:

[25/Aug/2018 11:30:25] ERROR [league.views:42] Caught exception in my_view()
Traceback (most recent call last):
  File "/home/tennis/tennis.pythonanywhere.com/website/league/views.py", line 40, in my_view
    pubnub.publish().channel('MyDemoChannel').message({"text": "Message from my_view()"}).async(publish_callback)
  File "/home/tennis/.virtualenvs/tennis.pythonanywhere.com/lib/python3.6/site-packages/pubnub/endpoints/endpoint.py", line 116, in async
    cancellation_event=self._cancellation_event)
  File "/home/tennis/.virtualenvs/tennis.pythonanywhere.com/lib/python3.6/site-packages/pubnub/pubnub.py", line 68, in request_async
    callback, cancellation_event)
  File "/home/tennis/.virtualenvs/tennis.pythonanywhere.com/lib/python3.6/site-packages/pubnub/request_handlers/requests_handler.py", line 81, in async_request
    thread.start()
  File "/usr/lib/python3.6/threading.py", line 846, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

Thanks for any help.


Solution

  • Configuring and instantiating the PubNub object outside my_view() fixed the problem:

    from pubnub.pnconfiguration import PNConfiguration
    from pubnub.pubnub import PubNub
    
    pnconfig = PNConfiguration()
    
    pnconfig.subscribe_key = '<sub key>'
    pnconfig.publish_key = '<pub key>'
    pnconfig.ssl = False
    
    pubnub = PubNub(pnconfig)
    
    def my_view(request):
        try:
            pubnub.publish().channel('MyDemoChannel').message({"text": "Message from my_view()"}).async(publish_callback)
        except:
            logger.exception("Caught exception in my_view()")
    
            context = {'val_1': 1, 'val_2': 2}
            return render( request, 'my_app/my_view.html', context)
    
    
    def publish_callback(envelope, status):
        if not status.is_error():
            pass
        else:
            pass