Skip to content

Commit

Permalink
more fixes and improvements in event notification
Browse files Browse the repository at this point in the history
  • Loading branch information
ilius committed Dec 22, 2024
1 parent 5e5893c commit b25cea5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 41 deletions.
21 changes: 12 additions & 9 deletions scal3/event_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -2250,15 +2250,16 @@ def afterModify(self):
self.setId()
self.modified = now() # FIXME
# self.parent.eventsModified = self.modified
# ---
if self.parent and self.id in self.parent.idList:
rulesHash = self.getRulesHash()
# what if self.notifyBefore is changed? BUG FIXME
if rulesHash != self.rulesHash:
self.parent.updateOccurrenceEvent(self)
self.rulesHash = rulesHash
else: # None or enbale=False

def afterAddedToGroup(self):
if not (self.parent and self.id in self.parent.idList):
self.rulesHash = ""
return

rulesHash = self.getRulesHash()
if self.notifiers or rulesHash != self.rulesHash:
self.parent.updateOccurrenceEvent(self)
self.rulesHash = rulesHash

def getNotifyBeforeSec(self):
return self.notifyBefore[0] * self.notifyBefore[1]
Expand Down Expand Up @@ -4534,6 +4535,8 @@ def updateOccurrenceEvent(self, event: Event) -> None:

if event.notifiers:
self.notificationEnabled = True
for t0, t1 in occur.getTimeRangeList():
self.notifyOccur.add(t0 - event.getNotifyBeforeSec(), t1, event.id)

def initOccurrence(self) -> None:
from scal3.event_search_tree import EventSearchTree
Expand All @@ -4548,7 +4551,7 @@ def initOccurrence(self) -> None:
def clear(self) -> None:
self.occur.clear()
self.occurCount = 0
self.notificationEnabled = True
self.notificationEnabled = False

def addOccur(self, t0: float, t1: float, eid: int) -> None:
self.occur.add(t0, t1, eid)
Expand Down
62 changes: 40 additions & 22 deletions scal3/event_notification_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
# Also avalable in /usr/share/common-licenses/GPL on Debian systems
# or /usr/share/licenses/common/GPL3/license.txt on ArchLinux

from scal3 import logger
from __future__ import annotations

from scal3 import event_lib, logger

log = logger.get()

import os
import threading
from queue import Empty, Queue

# from sched import scheduler
from threading import Thread
Expand All @@ -44,22 +47,38 @@ def stop(self):
for thread in self.byGroup.values():
thread.cancel()

def checkGroup(self, group):
def _startGroup(self, group: event_lib.EventGroup):
log.info(f"EventNotificationManager: {group=}: creating thread")
thread = EventGroupNotificationThread(group)
self.byGroup[group.id] = thread
thread.start()

def checkGroup(self, group: event_lib.EventGroup):
# log.debug(f"EventNotificationManager.checkGroup: {group=}")
if not group.enable:
if not (group.enable and group.notificationEnabled):
return

log.info(f"EventNotificationManager.checkGroup: {group=}")

thread = self.byGroup.get(group.id)
if thread is not None and thread.is_alive():
return
if not group.notificationEnabled:

self._startGroup(group)

def checkEvent(self, group: event_lib.EventGroup, event: event_lib.Event):
if not (group.enable and group.notificationEnabled):
log.info("EventNotificationManager.checkEvent: not enabled")
return

log.info(f"EventNotificationManager.checkEvent: {group=}, {event=}")

thread = self.byGroup.get(group.id)
if thread is not None and thread.is_alive():
thread.reCalc()
thread.checkEvent(event)
return

log.info(f"EventNotificationManager.checkGroup: {group=}: creating thread")
thread = EventGroupNotificationThread(group)
self.byGroup[group.id] = thread
thread.start()
self._startGroup(group)


class EventGroupNotificationThread(Thread):
Expand All @@ -72,6 +91,8 @@ def __init__(self, group):
self.group = group

self.sent = set()
self._stop_event = threading.Event()
self._new_events = Queue()

# self.sch: sched.scheduler | None = None
# threading.Timer is a subclass of threading.Thread
Expand All @@ -86,20 +107,15 @@ def __init__(self, group):
target=self.mainLoop,
)

self._stop_event = threading.Event()
self._recalc_event = threading.Event()

def cancel(self):
log.debug("EventGroupNotificationThread.cancel")
self._stop_event.set()

def stopped(self):
return self._stop_event.is_set()

def reCalc(self):
log.info("EventGroupNotificationThread.reCalc ----------------")
self.sent = set()
self._recalc_event.set()
def checkEvent(self, event: event_lib.Event):
self._new_events.put_nowait(event)

def sleep(self, seconds: float):
step = self.sleepSeconds
Expand All @@ -113,15 +129,17 @@ def mainLoop(self):
interval = self.interval
sleepSeconds = self.sleepSeconds
while not self._stop_event.is_set():
self._recalc_event.clear()
sleepUntil = perf_counter() + interval
log.debug(f"EventGroupNotificationThread: run: {self.group=}")
self._runStep()
log.debug(f"EventGroupNotificationThread: finished run: {self.group=}")
while not (
self._stop_event.is_set() or self._recalc_event.is_set()
) and perf_counter() < sleepUntil:
sleep(sleepSeconds)
while not self._stop_event.is_set() and perf_counter() < sleepUntil:
try:
event = self._new_events.get(block=True, timeout=sleepSeconds)
except Empty: # noqa: PERF203
continue
else:
event.checkNotify(self.finishFunc)

def finishFunc(self):
pass # FIXME: what to do here?
Expand Down Expand Up @@ -150,7 +168,7 @@ def _runStep(self):

tm = now()
items = list(group.notifyOccur.search(tm, tm + interval))
print(items)
log.info(f"{tm=}, {tm + interval=}, {items=}")

if not items:
return
Expand Down
22 changes: 12 additions & 10 deletions scal3/ui_gtk/event/editor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from gi.repository import GLib as glib

from scal3 import event_lib, locale_man, ui
from scal3.locale_man import tr as _
Expand Down Expand Up @@ -143,10 +142,18 @@ def run(self):
parentWin.present()
return None
self.activeWidget.updateVars()
self.event.afterModify()
self.event.save()

event = self.event
group = event.parent
event.afterModify()
event.save()
if self.isNew:
group.add(event)
group.save()
event.afterAddedToGroup()
event_lib.lastIds.save()
glib.timeout_add_seconds(1, ui.eventNotif.checkGroup, self.event.parent)
ui.eventNotif.checkEvent(group, event)

self.destroy()
# -----
if self.event.isSingleOccur:
Expand All @@ -172,14 +179,9 @@ def addNewEvent(group, eventType, typeChangable=False, **kwargs):
event = group.create(eventType)
if eventType == "custom": # FIXME
typeChangable = True
event = EventEditorDialog(
return EventEditorDialog(
event,
typeChangable=typeChangable,
isNew=True,
**kwargs,
).run()
if event is None:
return
group.add(event)
group.save()
return event

0 comments on commit b25cea5

Please sign in to comment.