mirror of
https://github.com/django/daphne.git
synced 2025-05-09 01:53:50 +03:00
* Add Delay Protocol Server Add a process that listens to a specific channel and delays incoming messages by a given time. * Add custom django command rundelay * Add test suite * Implements #115 * Add channels.delay app * Add AppConfig * Move rundelay command to channels.delay app * Refactor DelayedMessage into model Move login into a database backed model. * Update Worker * Add migration * Add delay docs page * Add to TOC * Fix import sorting * Add ASGI spec document for Delay Protocol * Update channels.delay doc with new channel name * remove interval docs * Refactor Delay to use milliseconds instead of seconds Use milliseconds as the default unit. Gives more control to developers. * Remove interval logic from DelayedMessage * Remove interval tests * Tweak test logic to use milliseconds
45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
import json
|
|
from datetime import timedelta
|
|
|
|
from django.db import models
|
|
from django.utils import timezone
|
|
|
|
from channels import DEFAULT_CHANNEL_LAYER, Channel, channel_layers
|
|
|
|
|
|
class DelayedMessageQuerySet(models.QuerySet):
|
|
|
|
def is_due(self):
|
|
return self.filter(due_date__lte=timezone.now())
|
|
|
|
|
|
class DelayedMessage(models.Model):
|
|
|
|
due_date = models.DateTimeField(db_index=True)
|
|
channel_name = models.CharField(max_length=512)
|
|
content = models.TextField()
|
|
|
|
objects = DelayedMessageQuerySet.as_manager()
|
|
|
|
@property
|
|
def delay(self):
|
|
return self._delay
|
|
|
|
@delay.setter
|
|
def delay(self, milliseconds):
|
|
self._delay = milliseconds
|
|
self.due_date = timezone.now() + timedelta(milliseconds=milliseconds)
|
|
|
|
def send(self, channel_layer=None):
|
|
"""
|
|
Sends the message on the configured channel with the stored content.
|
|
|
|
Deletes the DelayedMessage record.
|
|
|
|
Args:
|
|
channel_layer: optional channel_layer to use
|
|
"""
|
|
channel_layer = channel_layer or channel_layers[DEFAULT_CHANNEL_LAYER]
|
|
Channel(self.channel_name, channel_layer=channel_layer).send(json.loads(self.content), immediately=True)
|
|
self.delete()
|