Permalink
Browse files

Improve sockets implementation to not be simple pooling

  • Loading branch information...
overshard committed Oct 20, 2018
1 parent c55814b commit 74aa859e7eaadeacfa71910ac783820e96207966
Showing with 33 additions and 34 deletions.
  1. +3 −12 client/static_src/plugins/socket.js
  2. +18 −0 core/signals.py
  3. +12 −22 sockets/consumers.py
@@ -19,21 +19,12 @@ export default {
updateSocket.onmessage = e => {
let updateData = JSON.parse(e.data);
if (updateData.tasks != store.getters['tasks/getNumberOfTasks'])
if (updateData.model == 'Task')
store.dispatch('tasks/getTasks');
if (updateData.clients != store.getters['clients/getNumberOfClients'])
if (updateData.model == 'Client')
store.dispatch('clients/getClients');
if (updateData.projects != store.getters['clients/getNumberOfProjects'])
if (updateData.model == 'Project')
store.dispatch('clients/getProjects');
};
function checkForUpdates() {
setTimeout(() => {
updateSocket.send('');
checkForUpdates();
}, 5000);
}
checkForUpdates();
},
};
View
@@ -2,6 +2,9 @@
from django.db.models.signals import post_save
from django.dispatch import receiver
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from conf.utils import current_site_id
@@ -18,3 +21,18 @@ def add_current_site(sender, instance, **kwargs):
if not instance.sites.all():
instance.sites.set(Site.objects.filter(id=current_site_id()))
instance.save()
@receiver(post_save)
def sync_clients(sender, instance, **kwargs):
"""
Use django channels to sync all our current clients.
"""
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'sync_clients',
{
'type': 'sync_clients.save',
'model': sender.__name__,
},
)
View
@@ -1,34 +1,24 @@
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from core.models import Task, Client, Project
class UpdateConsumer(AsyncWebsocketConsumer):
# TODO: This really should use channel layers and not something as janky as
# storing everything currently avaliable on connection and double check on
# polling. That defeats the purpose of using websockets.
"""
Goes with our core signal that, on model update, sends a message to all
channels in the group to sync the UI.
"""
async def connect(self):
await self.accept()
await self.channel_layer.group_add(
'sync_clients', self.channel_name)
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
'sync_clients', self.channel_name)
async def receive(self, text_data):
async def sync_clients_save(self, event):
await self.send(json.dumps({
'tasks': await self.get_task_count(),
'clients': await self.get_client_count(),
'projects': await self.get_project_count(),
'model': event['model'],
}))
@database_sync_to_async
def get_task_count(self):
return Task.objects.count()
@database_sync_to_async
def get_client_count(self):
return Client.objects.filter(archive=False).count()
@database_sync_to_async
def get_project_count(self):
return Project.objects.filter(archive=False).count()

0 comments on commit 74aa859

Please sign in to comment.