Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Purge old announcements #3

Merged
merged 2 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ If the latest announcement has been cleared or there are no announcements yet, a
There's a hook in the configuration that lets you add a custom message above all the annoucements.
A good use for this message would be to include a link to a more general system status or message of the day (MOTD) page.

## Announcement Lifetime

Announcements are retained in the queue for up to some configurable lifetime in days.
After that they are purged automatically.
By default announcements stay in the queue for a week.

## Persisted Announcements

By default the service does nothing to persist announcements.
Expand All @@ -106,7 +112,3 @@ On update, the file is over-written to reflect the current state of the queue.
This way if the service is restarted, those old announcements aren't lost.
The persistence file is just JSON.
**BE CERTAIN** access to this file is protected!

## Things That Could Use Work

We should put a cap on the size of the announcement queue, or expire them after some time period.
6 changes: 6 additions & 0 deletions announcement_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
# AnnouncementQueue(LoggingConfigurable) configuration
#------------------------------------------------------------------------------

## Number of days to retain announcements.
#
# Announcements that have been in the queue for this many days are purged from
# the queue.
#c.AnnouncementQueue.lifetime_days = 7.0

## File path where announcements persist as JSON.
#
# For a persistent announcement queue, this parameter must be set to a non-empty
Expand Down
23 changes: 22 additions & 1 deletion jupyterhub_announcement/announcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from tornado import escape, gen, ioloop, web

from traitlets.config import Application, LoggingConfigurable
from traitlets import Bool, Dict, Integer, List, Unicode, default
from traitlets import Bool, Dict, Float, Integer, List, Unicode, default


class _JSONEncoder(json.JSONEncoder):
Expand Down Expand Up @@ -56,6 +56,13 @@ class AnnouncementQueue(LoggingConfigurable):
announcements will not be persisted on updates to the queue."""
).tag(config=True)

lifetime_days = Float(7.0,
help="""Number of days to retain announcements.

Announcements that have been in the queue for this many days are
purged from the queue."""
).tag(config=True)

def __init__(self, **kwargs):
super().__init__(**kwargs)

Expand Down Expand Up @@ -96,6 +103,16 @@ def _persist(self):
with open(self.persist_path, "w") as stream:
json.dump(self.announcements, stream, cls=_JSONEncoder, indent=2)

def purge(self):
max_age = datetime.timedelta(days=self.lifetime_days)
now = datetime.datetime.now()
old_count = len(self.announcements)
self.announcements = [a for a in self.announcements
if now - a["timestamp"] < max_age]
if self.persist_path and len(self.announcements) < old_count:
self.log.info(f"persisting queue to {self.persist_path}")
self._handle_persist()


class AnnouncementHandler(HubAuthenticated, web.RequestHandler):

Expand Down Expand Up @@ -261,6 +278,10 @@ def init_queue(self):

def start(self):
self.app.listen(self.port)
def purge_callback():
self.queue.purge()
c = ioloop.PeriodicCallback(purge_callback, 300000)
c.start()
ioloop.IOLoop.current().start()


Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name='jupyterhub-announcement',
version='0.2.0',
version='0.3.0',
description='JupyterHub Announcement Service',
author='R. C. Thomas',
author_email='[email protected]',
Expand Down