-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cache the latest operation status and setting (#35)
This resolves #34. I implemented as follows. - `ChannelCache` to store the latest operation status and setting for each channel. - `utils/util.py` to offer the utility functions to get whether the specific channel/WLM is currently running. (Replaced with `get_running_status()` in `operation/views.py`.) If you aren't familiar with Django signals, please refer to [docs](https://docs.djangoproject.com/en/5.1/topics/signals/).
- Loading branch information
Showing
10 changed files
with
121 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"""Module for caching the channel status.""" | ||
|
||
from collections import defaultdict | ||
|
||
from operation.models import Operation | ||
from setting.models import Setting | ||
|
||
class ChannelCache: | ||
"""Cache for channel status.""" | ||
|
||
def __init__(self): | ||
# outer key: Channel__channel, inner key: User__username | ||
self._channel_to_operation: defaultdict[int, dict[str, Operation]] = defaultdict(dict) | ||
# key: Channel__channel | ||
self._channel_to_setting: dict[int, Setting] = {} | ||
self._load() | ||
|
||
def _load(self): | ||
"""Loads all channels status.""" | ||
operations = (Operation.objects.order_by('channel', 'user', '-occurred_at') | ||
.distinct('channel', 'user')) | ||
for operation in operations: | ||
(self._channel_to_operation | ||
[operation.channel.channel][operation.user.username]) = operation | ||
settings = Setting.objects.order_by('channel', '-created_at').distinct('channel') | ||
for setting in settings: | ||
self._channel_to_setting[setting.channel.channel] = setting | ||
|
||
def set_operation(self, operation: Operation): | ||
"""Stores the given operation as the latest. | ||
Args: | ||
operation: The latest operation. | ||
""" | ||
self._channel_to_operation[operation.channel.channel][operation.user.username] = operation | ||
|
||
def set_setting(self, setting: Setting): | ||
"""Stores the given setting as the latest. | ||
Args: | ||
setting: The latest setting. | ||
""" | ||
self._channel_to_setting[setting.channel.channel] = setting | ||
|
||
def get_operations(self, channel: int) -> dict[str, Operation]: | ||
"""Returns the latest operation status for the given channel. | ||
Args: | ||
channel: Target channel. | ||
Returns: | ||
Dictionary with user name as the key and the latest operation status as the value. | ||
""" | ||
return self._channel_to_operation[channel] | ||
|
||
def get_setting(self, channel: int) -> Setting: | ||
"""Returns the latest setting for the given channel. | ||
Args: | ||
channel: Target channel. | ||
Returns: | ||
The latest setting. | ||
""" | ||
return self._channel_to_setting[channel] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class OperationConfig(AppConfig): | ||
default_auto_field = 'django.db.models.BigAutoField' | ||
name = 'operation' | ||
|
||
def ready(self): | ||
from . import signals # pylint: disable=import-outside-toplevel, unused-import |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from django.db.models.signals import post_save | ||
from django.dispatch import receiver | ||
from django.conf import settings | ||
|
||
from .models import Operation | ||
|
||
@receiver(post_save, sender=Operation) | ||
def handle_model_save(sender, **kwargs): # pylint: disable=unused-argument | ||
"""Updates the channel cache whenever an operation status is saved.""" | ||
settings.CHANNEL_CACHE.set_operation(kwargs['instance']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from django.db.models.signals import post_save | ||
from django.dispatch import receiver | ||
from django.conf import settings | ||
|
||
from .models import Setting | ||
|
||
@receiver(post_save, sender=Setting) | ||
def handle_model_save(sender, **kwargs): # pylint: disable=unused-argument | ||
"""Updates the channel cache whenever an operation status is saved.""" | ||
settings.CHANNEL_CACHE.set_setting(kwargs['instance']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from django.conf import settings | ||
|
||
from channel.models import Channel | ||
|
||
def is_channel_running(channel: int) -> bool: | ||
"""Returns whether the given channel is currently running. | ||
Args: | ||
channel: Target channel. | ||
""" | ||
operations = settings.CHANNEL_CACHE.get_operations(channel) | ||
return any(op.on for op in operations.values()) | ||
|
||
|
||
def is_wlm_running() -> bool: | ||
"""Returns whether the WLM is currently running.""" | ||
return any(is_channel_running(channel.channel) for channel in Channel.objects.all()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,3 +143,5 @@ | |
AUTH_USER_MODEL = 'user.User' | ||
|
||
MESSAGE_QUEUE = MessageQueue() | ||
|
||
CHANNEL_CACHE = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters