]> code.delx.au - offlineimap/blobdiff - offlineimap/init.py
Bug#502779: Sync accounts in order of general.accounts option
[offlineimap] / offlineimap / init.py
index 8485511599f87938b78f3d35be94f93a7849cb07..8d888b43d8c0884d80ef22da728be215f065edeb 100644 (file)
@@ -16,8 +16,7 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
-import imaplib
-from offlineimap import imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
+from offlineimap import imaplib2, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
 from offlineimap.localeval import LocalEval
 from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
 from offlineimap.ui import UIBase
 from offlineimap.localeval import LocalEval
 from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
 from offlineimap.ui import UIBase
@@ -26,6 +25,7 @@ from offlineimap.CustomConfig import CustomConfigParser
 from threading import *
 import threading, socket
 from getopt import getopt
 from threading import *
 import threading, socket
 from getopt import getopt
+import signal
 
 try:
     import fcntl
 
 try:
     import fcntl
@@ -102,7 +102,7 @@ def startup(versionno):
         for debugtype in options['-d'].split(','):
             ui.add_debug(debugtype.strip())
             if debugtype == 'imap':
         for debugtype in options['-d'].split(','):
             ui.add_debug(debugtype.strip())
             if debugtype == 'imap':
-                imaplib.Debug = 5
+                imaplib2.Debug = 5
             if debugtype == 'thread':
                 threading._VERBOSE = 1
 
             if debugtype == 'thread':
                 threading._VERBOSE = 1
 
@@ -131,6 +131,11 @@ def startup(versionno):
 
     lock(config, ui)
 
 
     lock(config, ui)
 
+    def sigterm_handler(signum, frame):
+        # die immediately
+        ui.terminate(errormsg="terminating...")
+    signal.signal(signal.SIGTERM,sigterm_handler)
+
     try:
         pidfd = open(config.getmetadatadir() + "/pid", "w")
         pidfd.write(str(os.getpid()) + "\n")
     try:
         pidfd = open(config.getmetadatadir() + "/pid", "w")
         pidfd.write(str(os.getpid()) + "\n")
@@ -153,7 +158,7 @@ def startup(versionno):
         activeaccounts = activeaccounts.split(",")
         allaccounts = accounts.AccountHashGenerator(config)
 
         activeaccounts = activeaccounts.split(",")
         allaccounts = accounts.AccountHashGenerator(config)
 
-        syncaccounts = {}
+        syncaccounts = []
         for account in activeaccounts:
             if account not in allaccounts:
                 if len(allaccounts) == 0:
         for account in activeaccounts:
             if account not in allaccounts:
                 if len(allaccounts) == 0:
@@ -163,7 +168,8 @@ def startup(versionno):
                     for name in allaccounts.keys():
                         errormsg += '\n%s'%name
                 ui.terminate(1, errortitle = 'Unknown Account "%s"'%account, errormsg = errormsg)
                     for name in allaccounts.keys():
                         errormsg += '\n%s'%name
                 ui.terminate(1, errortitle = 'Unknown Account "%s"'%account, errormsg = errormsg)
-            syncaccounts[account] = allaccounts[account]
+            if account not in syncaccounts:
+                syncaccounts.append(account)
 
         server = None
         remoterepos = None
 
         server = None
         remoterepos = None
@@ -183,12 +189,31 @@ def startup(versionno):
                 else:
                     threadutil.initInstanceLimit(instancename,
                                                  config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
                 else:
                     threadutil.initInstanceLimit(instancename,
                                                  config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
+        siglisteners = []
+        def sig_handler(signum, frame):
+            if signum == signal.SIGUSR1:
+                # tell each account to do a full sync asap
+                signum = (1,)
+            elif signum == signal.SIGHUP:
+                # tell each account to die asap
+                signum = (2,)
+            elif signum == signal.SIGUSR2:
+                # tell each account to do a full sync asap, then die
+                signum = (1, 2)
+            # one listener per account thread (up to maxsyncaccounts)
+            for listener in siglisteners:
+                for sig in signum:
+                    listener.put_nowait(sig)
+        signal.signal(signal.SIGHUP,sig_handler)
+        signal.signal(signal.SIGUSR1,sig_handler)
+        signal.signal(signal.SIGUSR2,sig_handler)
 
         threadutil.initexitnotify()
         t = ExitNotifyThread(target=syncmaster.syncitall,
                              name='Sync Runner',
                              kwargs = {'accounts': syncaccounts,
 
         threadutil.initexitnotify()
         t = ExitNotifyThread(target=syncmaster.syncitall,
                              name='Sync Runner',
                              kwargs = {'accounts': syncaccounts,
-                                       'config': config})
+                                       'config': config,
+                                       'siglisteners': siglisteners})
         t.setDaemon(1)
         t.start()
     except:
         t.setDaemon(1)
         t.start()
     except: