monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] [PATCH] change monotone-dumb to use automate stdio


From: Zbynek Winkler
Subject: [Monotone-devel] [PATCH] change monotone-dumb to use automate stdio
Date: Tue, 18 Oct 2005 20:20:53 +0200
User-agent: Debian Thunderbird 1.0.2 (X11/20050602)

I've updated monotone.py from net.venge.monotone.dumb branch to use 'automate stdio' for all automate commands. It avoids respawning the monotone process for each command. However, for it to be of a real use, more automate commands are needed (especially packet handling).
Zbynek

--
http://zw.matfyz.cz/     http://robotika.cz/
Faculty of Mathematics and Physics, Charles University, Prague, Czech Republic

# 
# old_revision [2d9e5494a839bf24c7a9434142b53d5c627cbf59]
# 
# patch "monotone.py"
#  from [721acaadb1b9b3d40b62061db53f4bbb4ce4cb4c]
#    to [24d10d173e225a5f3cdb2085473ca927c32904f4]
# 
============================================================
--- monotone.py 721acaadb1b9b3d40b62061db53f4bbb4ce4cb4c
+++ monotone.py 24d10d173e225a5f3cdb2085473ca927c32904f4
@@ -36,7 +36,11 @@
     def __init__(self, db, executable="monotone"):
         self.db = db
         self.executable = executable
+        self.process = None
 
+    def __del__(self):
+        self.ensure_stopped()
+
     def init_db(self):
         self.run_monotone(["db", "init"])
 
@@ -48,18 +52,17 @@
             self.init_db()
 
     def revisions_list(self):
-        output = self.run_monotone(["automate", "select", "i:"])
+        output = self.automate("select", "i:")
         return output.split()
     
     def toposort(self, revisions):
-        output = self.run_monotone(["automate", "toposort", "address@hidden"],
-                                   "\n".join(revisions) + "\n")
+        output = self.automate("toposort", *revisions)
         sorted = output.split()
         assert len(sorted) == len(revisions)
         return sorted
 
     def get_revision(self, rid):
-        return self.run_monotone(["automate", "get_revision", rid])
+        return self.automate("get_revision", rid)
 
     def get_pubkey_packet(self, keyid):
         return self.run_monotone(["pubkey", keyid])
@@ -92,7 +95,7 @@
         return packets
 
     def key_names(self):
-        output = self.run_monotone(["automate", "keys"])
+        output = self.automate("keys")
         print output
         keys_parsed = self.basic_io_parser(output)
         ids = {}
@@ -105,6 +108,7 @@
 
     # returns output as a string, raises an error on error
     def run_monotone(self, args, input=None):
+        self.ensure_stopped()
         process = subprocess.Popen([self.executable, "--db", self.db] + args,
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
@@ -113,7 +117,45 @@
         if process.returncode:
             raise MonotoneError, stderr
         return stdout
+    
+    def ensure_running(self):
+        if not self.process:
+            self.process = subprocess.Popen([self.executable, "--db", self.db, 
"automate", "stdio"],
+                                   stdin=subprocess.PIPE,
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.PIPE)
+    
+    def ensure_stopped(self):
+        if self.process:    
+            self.process.stdin.close()
+            self.process.wait()
+            self.process = None
+    
+    def automate(self, *args):
+        def formater(args):
+            return "l" + "".join([str(len(command))+":"+command for command in 
args]) + "e"
 
+        def parser(pipe):
+            def get_fields():
+                for i in range(0,4):
+                    field = ""
+                    sep = pipe.read(1)
+                    while not sep == ":":
+                        field += sep
+                        sep = pipe.read(1)
+                    yield field
+            
+            data = "" 
+            while 1:
+                cmd, status, cont, size = get_fields()
+                data += pipe.read(int(size))
+                if cont != "m": break
+            return data
+            
+        self.ensure_running();
+        self.process.stdin.write(formater(args))
+        return parser(self.process.stdout)
+
     # feeds stuff into 'monotone read'
     def feeder(self):
         args = [self.executable, "--db", self.db, "read"]

reply via email to

[Prev in Thread] Current Thread [Next in Thread]