1
2"""
3    Demonstrate the use of h5py in SWMR mode to monitor the growth of a dataset
4    on notification of file modifications.
5
6    This demo uses pyinotify as a wrapper of Linux inotify.
7    https://pypi.python.org/pypi/pyinotify
8
9    Usage:
10            swmr_inotify_example.py [FILENAME [DATASETNAME]]
11
12              FILENAME:    name of file to monitor. Default: swmr.h5
13              DATASETNAME: name of dataset to monitor in DATAFILE. Default: data
14
15    This script will open the file in SWMR mode and monitor the shape of the
16    dataset on every write event (from inotify). If another application is
17    concurrently writing data to the file, the writer must have have switched
18    the file into SWMR mode before this script can open the file.
19"""
20import asyncore
21import pyinotify
22import sys
23import h5py
24import logging
25
26#assert h5py.version.hdf5_version_tuple >= (1,9,178), "SWMR requires HDF5 version >= 1.9.178"
27
28class EventHandler(pyinotify.ProcessEvent):
29
30    def monitor_dataset(self, filename, datasetname):
31        logging.info("Opening file %s", filename)
32        self.f = h5py.File(filename, 'r', libver='latest', swmr=True)
33        logging.debug("Looking up dataset %s"%datasetname)
34        self.dset = self.f[datasetname]
35
36        self.get_dset_shape()
37
38    def get_dset_shape(self):
39        logging.debug("Refreshing dataset")
40        self.dset.refresh()
41
42        logging.debug("Getting shape")
43        shape = self.dset.shape
44        logging.info("Read data shape: %s"%str(shape))
45        return shape
46
47    def read_dataset(self, latest):
48        logging.info("Reading out dataset [%d]"%latest)
49        self.dset[latest:]
50
51    def process_IN_MODIFY(self, event):
52        logging.debug("File modified!")
53        shape = self.get_dset_shape()
54        self.read_dataset(shape[0])
55
56    def process_IN_CLOSE_WRITE(self, event):
57        logging.info("File writer closed file")
58        self.get_dset_shape()
59        logging.debug("Good bye!")
60        sys.exit(0)
61
62
63if __name__ == "__main__":
64    logging.basicConfig(format='%(asctime)s  %(levelname)s\t%(message)s',level=logging.INFO)
65
66    file_name = "swmr.h5"
67    if len(sys.argv) > 1:
68        file_name = sys.argv[1]
69    dataset_name = "data"
70    if len(sys.argv) > 2:
71        dataset_name = sys.argv[2]
72
73
74    wm = pyinotify.WatchManager()  # Watch Manager
75    mask = pyinotify.IN_MODIFY | pyinotify.IN_CLOSE_WRITE
76    evh = EventHandler()
77    evh.monitor_dataset( file_name, dataset_name )
78
79    notifier = pyinotify.AsyncNotifier(wm, evh)
80    wdd = wm.add_watch(file_name, mask, rec=False)
81
82    # Sit in this loop() until the file writer closes the file
83    # or the user hits ctrl-c
84    asyncore.loop()
85