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

Make update/purge async, need aiofiles #13

Merged
merged 1 commit into from
May 13, 2022
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
34 changes: 18 additions & 16 deletions jupyterhub_announcement/announcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import sys

import aiofiles
from jinja2 import Environment, ChoiceLoader, FileSystemLoader, PrefixLoader
from jupyterhub.services.auth import HubOAuthenticated, HubOAuthCallbackHandler
from jupyterhub.handlers.static import LogoHandler
Expand Down Expand Up @@ -87,33 +88,35 @@ def _restore(self):
with open(self.persist_path, "r") as stream:
self.announcements = json.load(stream, object_hook=_datetime_hook)

def update(self, user, announcement=""):
async def update(self, user, announcement=""):
self.announcements.append(dict(user=user,
announcement=announcement,
timestamp=datetime.datetime.now()))
if self.persist_path:
self.log.info(f"persisting queue to {self.persist_path}")
self._handle_persist()
await self._handle_persist()

def _handle_persist(self):
async def _handle_persist(self):
try:
self._persist()
await self._persist()
except Exception as err:
self.log.error(f"failed to persist queue ({err})")

def _persist(self):
with open(self.persist_path, "w") as stream:
json.dump(self.announcements, stream, cls=_JSONEncoder, indent=2)
async def _persist(self):
async with aiofiles.open(self.persist_path, "w") as stream:
await stream.write(
json.dumps(self.announcements, cls=_JSONEncoder, indent=2)
)

def purge(self):
async 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()
await self._handle_persist()


class AnnouncementHandler(HubOAuthenticated, web.RequestHandler):
Expand Down Expand Up @@ -154,7 +157,6 @@ def initialize(self, queue, allow_origin):
super().initialize(queue)
self.allow_origin = allow_origin


def get(self):
latest = {"announcement": ""}
if self.queue.announcements:
Expand All @@ -174,13 +176,13 @@ class AnnouncementUpdateHandler(AnnouncementHandler):
allow_admin = True

@web.authenticated
def post(self):
async def post(self):
"""Update announcement"""
user = self.get_current_user()
sanitizer = Sanitizer()
# announcement = self.get_body_argument("announcement")
announcement = sanitizer.sanitize(self.get_body_argument("announcement"))
self.queue.update(user["name"], announcement)
await self.queue.update(user["name"], announcement)
self.redirect(self.application.reverse_url("view"))


Expand Down Expand Up @@ -337,10 +339,10 @@ def init_ssl_context(self):

def start(self):
self.app.listen(self.port, ssl_options=self.ssl_context)
def purge_callback():
self.queue.purge()
c = ioloop.PeriodicCallback(purge_callback, 300000)
c.start()
async def purge_loop():
await self.queue.purge()
await gen.sleep(300)
ioloop.IOLoop.current().add_callback(purge_loop)
ioloop.IOLoop.current().start()


Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
aiofiles
jupyterhub
html-sanitizer