7
7
import os
8
8
import queue
9
9
import sqlite3
10
- import inotify .adapters # type: ignore
11
10
import psutil
12
11
import re
13
12
import shutil
17
16
import sys
18
17
import tarfile
19
18
import time
19
+ import threading
20
20
from ou_dedetai .app import App
21
21
from packaging .version import Version
22
22
from pathlib import Path
27
27
from . import system
28
28
from . import wine
29
29
30
+ if sys .platform .startswith ("linux" ):
31
+ import inotify .adapters # type: ignore
32
+ elif sys .platform .startswith (("darwin" , "freebsd" , "dragonfly" , "netbsd" , "openbsd" )):
33
+ import select
30
34
31
35
def get_calling_function_name ():
32
36
if 'inspect' in sys .modules :
@@ -659,10 +663,6 @@ def watch_db(path: str, sql_statements: list[str]):
659
663
660
664
This function may run infinitely, spawn it on it's own thread
661
665
"""
662
- # Silence inotify logs
663
- logging .getLogger ('inotify' ).setLevel (logging .CRITICAL )
664
- i = inotify .adapters .Inotify ()
665
- i .add_watch (path )
666
666
667
667
def execute_sql (cur ):
668
668
# logging.debug(f"Executing SQL against {path}: {sql_statements}")
@@ -679,30 +679,57 @@ def execute_sql(cur):
679
679
680
680
# Execute once before we start the loop
681
681
execute_sql (cur )
682
- swallow_one = True
683
-
684
- # Keep track of if we've added -wal and -shm are added yet
685
- # They may not exist when we start
686
- watching_wal_and_shm = False
687
- for event in i .event_gen (yield_nones = False ):
688
- (_ , type_names , _ , _ ) = event
689
- # These files may not exist when it's executes for the first time
690
- if (
691
- not watching_wal_and_shm
692
- and Path (path + "-wal" ).exists ()
693
- and Path (path + "-shm" ).exists ()
694
- ):
695
- i .add_watch (path + "-wal" )
696
- i .add_watch (path + "-shm" )
697
- watching_wal_and_shm = True
698
-
699
- if 'IN_MODIFY' in type_names or 'IN_CLOSE_WRITE' in type_names :
700
- # Check to make sure that we aren't responding to our own write
701
- if swallow_one :
702
- swallow_one = False
703
- continue
704
- execute_sql (cur )
682
+ if sys .platform .startswith ("linux" ):
683
+ def monitor_inotify ():
684
+ """Monitor file changes using inotify."""
685
+ logging .getLogger ('inotify' ).setLevel (logging .CRITICAL )
686
+ i = inotify .adapters .Inotify ()
687
+ i .add_watch (path )
688
+
705
689
swallow_one = True
690
+
691
+ # Keep track of if we've added -wal and -shm are added yet
692
+ # They may not exist when we start
693
+ watching_wal_and_shm = False
694
+ for event in i .event_gen (yield_nones = False ):
695
+ (_ , type_names , _ , _ ) = event
696
+ # These files may not exist when it's executes for the first time
697
+ if (
698
+ not watching_wal_and_shm
699
+ and Path (path + "-wal" ).exists ()
700
+ and Path (path + "-shm" ).exists ()
701
+ ):
702
+ i .add_watch (path + "-wal" )
703
+ i .add_watch (path + "-shm" )
704
+ watching_wal_and_shm = True
705
+
706
+ if 'IN_MODIFY' in type_names or 'IN_CLOSE_WRITE' in type_names :
707
+ # Check to make sure that we aren't responding to our own write
708
+ if swallow_one :
709
+ swallow_one = False
710
+ continue
711
+ execute_sql (cur )
712
+ swallow_one = True
713
+
714
+ monitor_inotify ()
715
+
716
+ elif sys .platform .startswith (("darwin" , "freebsd" , "dragonfly" , "netbsd" , "openbsd" )):
717
+ def monitor_kqueue ():
718
+ """Monitor file changes using kqueue."""
719
+ kq = select .kqueue ()
720
+ fd = open (path , "rb" ) # Open file to track
721
+ kevent = select .kevent (fd .fileno (), filter = select .KQ_FILTER_VNODE ,
722
+ flags = select .KQ_EV_ADD | select .KQ_EV_ENABLE ,
723
+ fflags = select .KQ_NOTE_WRITE | select .KQ_NOTE_EXTEND )
724
+ kq .control ([kevent ], 0 , 0 )
725
+
726
+ while True :
727
+ events = kq .control (None , 1 ) # Block until event occurs
728
+ if events :
729
+ execute_sql ()
730
+
731
+ monitor_kqueue ()
732
+
706
733
# Shouldn't be possible to get here, but on the off-chance it happens,
707
734
# we'd like to know and cleanup
708
735
logging .debug (f"Stopped watching { path } " )
0 commit comments