Parham.rm
Parham.rm

Reputation: 133

Using django channels with threading.Thead

I'm using django channels in order to send multiple responses to a single request. The code is something like this:

class terminal(WebsocketConsumer):
   def connect(self):
       self.accept()

   def disconnect(self, close_code):
       self.close()

   def receive(self, text_data):
       data_json = json.loads(text_data)
       if data_json['event'] == 'initial':
          self.t = threading.Thread(target=self.send_data)
          self.t.daemon = True
          self.t.start()
       elif data_json['event'] == 'pause':
          pass
       print("done")

   def send_data(self):
       n = 100
       end = 1000000
       while (n + 1 < end)
          # some code
          self.send(json.dumps({'data':data})
          n += 1

I've used thread to be able to listen to pause and other events while data is being sent to the client. The problem is that the thread keeps running after websocket gets disconnected.

Is there a way to kill a python thread in disconnect function? Or maybe a better way to implement this?

Upvotes: 2

Views: 2488

Answers (1)

ostcar
ostcar

Reputation: 161

There are probably many ways to solve your problem. I would suggest, you use the function sync_to_async() from asgiref.sync. It creates a new thread and "awaits", until it is finished. "awaits" means, that in an async context, other code can run in the meantime.

To call sync_to_async() you have to use a AsyncWebsocketConsumer

class terminal(AsyncWebsocketConsumer):
   async def connect(self):
       awaitself.accept()

   async def disconnect(self, close_code):
       await self.close()

   async def receive(self, text_data):
       data_json = json.loads(text_data)
       if data_json['event'] == 'initial':
          await sync_to_async(self.send_data)()
       elif data_json['event'] == 'pause':
          pass
       print("done")

   def send_data(self):
       n = 100
       end = 1000000
       while (n + 1 < end)
          # some code
          sync_to_async(self.send)(json.dumps({'data':data})
          n += 1

Upvotes: 1

Related Questions