]> git.phdru.name Git - bookmarks_db.git/blob - Robots/bkmk_rforking.py
4c4c098daae740d2278e6227ad86ca5b4457dc0b
[bookmarks_db.git] / Robots / bkmk_rforking.py
1 """
2    Forking robot
3
4    Written by Broytman. Copyright (C) 2000-2010 PhiloSoft Design.
5 """
6
7
8 try:
9    import cPickle
10    pickle = cPickle
11 except ImportError:
12    import pickle
13
14 import sys, os
15 from subproc import Subprocess, RecordFile
16
17 # This is to catch 'close failed: [Errno 9] Bad file descriptor' message
18 # from os.close() in Subprocess.die() and errors from from the subprocess.
19 sys.stderr = open("err.log", 'a')
20
21 check_subp = None
22 subp_pipe = None
23
24 def stop_subp(log):
25    global check_subp, subp_pipe
26    if check_subp:
27       if log: log("   restarting hanging subprocess")
28       del check_subp
29    del subp_pipe
30
31 def restart_subp(log):
32    global check_subp, subp_pipe
33    stop_subp(log)
34
35    check_subp = Subprocess("%s/Robots/bkmk_rforking_sub.py" % os.path.dirname(sys.argv[0]),
36       control_stderr=True)
37    subp_pipe = RecordFile(check_subp)
38
39
40 from bkmk_objects import Robot
41
42 class robot_forking(Robot):
43    def check_url(self, bookmark):
44       if not check_subp:
45          restart_subp(self.log) # Not restart, just start afresh
46
47       try:
48          save_parent = bookmark.parent
49          bookmark.parent = None
50
51          bookmark.tempfname = self.tempfname
52          subp_pipe.write_record(pickle.dumps(bookmark))
53
54          if check_subp.waitForPendingChar(60): # wait a minute
55             new_b = pickle.loads(subp_pipe.read_record())
56             for attr in ("error", "no_error",
57                   "moved", "size", "md5", "real_title",
58                   "last_tested", "last_modified", "test_time", "icon"):
59                if hasattr(new_b, attr):
60                   setattr(bookmark, attr, getattr(new_b, attr))
61          else:
62             bookmark.error = "Subprocess connection timed out"
63             restart_subp(self.log)
64
65          bookmark.parent = save_parent
66
67          while True:
68             error = check_subp.readPendingErrLine()
69             if not error:
70                break
71             sys.stderr.write("(subp) " + error)
72          sys.stderr.flush()
73
74       except KeyboardInterrupt:
75          return 0
76
77       # Tested
78       return 1
79
80
81    def stop(self):
82       stop_subp(None) # Stop subprocess; do not log restarting