pvl/syslog/tail.py
changeset 137 e312f27b807d
parent 122 f742c866c765
child 172 2c971f7f28fe
--- a/pvl/syslog/tail.py	Sun Jan 13 12:57:30 2013 +0200
+++ b/pvl/syslog/tail.py	Sun Jan 13 12:57:49 2013 +0200
@@ -21,16 +21,14 @@
         log.debug("%s", path)
 
         self.path = path
-        self.reopen()
+        self.file = self.stat = None # closed
+
+        self.open()
 
         if skip :
             self.skip()
    
-    def open (self) :
-        log.debug("%s", self)
-        return open(self.path, 'r')
-
-    def stat (self) :
+    def _stat (self) :
         """
             Return a key identifying the file at our path.
         """
@@ -39,25 +37,38 @@
 
         stat = st.st_dev, st.st_ino
 
-        log.debug("%s: %s", self, stat)
-
         return stat
- 
-    def reopen (self) :
+
+    def _open (self) :
         """
-            Re-initialize our file state from path.
+            Return the opened file.
         """
 
-        # XXX: use fstat for "atomic" open+stat?
-        self.file = self.open()
-        self._stat = self.stat()
+        return open(self.path, 'r')
+
+    def open (self) :
+        """
+            Re-opens our file when closed.
+
+            Raises ValueError if already open.
+        """
+
+        if self.file is None :
+            # XXX: use fstat for "atomic" open+stat?
+            self.file = self._open()
+            self.stat = self._stat()
+
+            log.debug("%s: %s: %s", self, self.file, self.stat)
+
+        else :
+            raise ValueError("%s: open already open tail" % (self, ))
 
     def changed (self) :
         """
             Has the underlying file changed?
         """
 
-        return self.stat() != self._stat
+        return self._stat() != self.stat
 
     def readline (self) :
         """
@@ -94,7 +105,9 @@
 
             elif self.changed() :
                 log.debug("EOF: reopen")
-                self.reopen()
+                
+                self.close()
+                self.open()
                 
                 if eof_mark :
                     yield None # special token
@@ -113,9 +126,23 @@
             Skip any available lines.
         """
 
+        log.debug("%s", self)
+
         for line in self.readlines() :
             pass
 
+    def close (self) :
+        """
+            Close our file, if open. Further operations raise ValueError.
+
+            log.warn's if already closed.
+        """
+        
+        if self.file :
+            log.debug("%s", self)
+            self.file.close()
+        else :
+            log.warn("%s: close on already closed tail", self)
 
     def __str__ (self) :
         return self.path