/ src / shutdown.py.bak
shutdown.py.bak
 1  """shutdown function"""
 2  
 3  import os
 4  import threading
 5  import time
 6  
 7  from six.moves import queue
 8  
 9  import state
10  from debug import logger
11  from helper_sql import sqlQuery, sqlStoredProcedure
12  from network import StoppableThread
13  from network.knownnodes import saveKnownNodes
14  from queues import (
15      addressGeneratorQueue, objectProcessorQueue, UISignalQueue, workerQueue)
16  
17  
18  def doCleanShutdown():
19      """
20      Used to tell all the treads to finish work and exit.
21      """
22      state.shutdown = 1
23  
24      objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
25      for thread in threading.enumerate():
26          if thread.isAlive() and isinstance(thread, StoppableThread):
27              thread.stopThread()
28  
29      UISignalQueue.put((
30          'updateStatusBar',
31          'Saving the knownNodes list of peers to disk...'))
32      logger.info('Saving knownNodes list of peers to disk')
33      saveKnownNodes()
34      logger.info('Done saving knownNodes list of peers to disk')
35      UISignalQueue.put((
36          'updateStatusBar',
37          'Done saving the knownNodes list of peers to disk.'))
38      logger.info('Flushing inventory in memory out to disk...')
39      UISignalQueue.put((
40          'updateStatusBar',
41          'Flushing inventory in memory out to disk.'
42          ' This should normally only take a second...'))
43      state.Inventory.flush()
44  
45      # Verify that the objectProcessor has finished exiting. It should have
46      # incremented the shutdown variable from 1 to 2. This must finish before
47      # we command the sqlThread to exit.
48      while state.shutdown == 1:
49          time.sleep(.1)
50  
51      # Wait long enough to guarantee that any running proof of work worker
52      # threads will check the shutdown variable and exit. If the main thread
53      # closes before they do then they won't stop.
54      time.sleep(.25)
55  
56      for thread in threading.enumerate():
57          if (
58              thread is not threading.currentThread()
59              and isinstance(thread, StoppableThread)
60              and thread.name != 'SQL'
61          ):
62              logger.debug("Waiting for thread %s", thread.name)
63              thread.join()
64  
65      # This one last useless query will guarantee that the previous flush
66      # committed and that the
67      # objectProcessorThread committed before we close the program.
68      sqlQuery('SELECT address FROM subscriptions')
69      logger.info('Finished flushing inventory.')
70      sqlStoredProcedure('exit')
71  
72      # flush queues
73      for q in (
74              workerQueue, UISignalQueue, addressGeneratorQueue,
75              objectProcessorQueue):
76          while True:
77              try:
78                  q.get(False)
79                  q.task_done()
80              except queue.Empty:
81                  break
82  
83      if state.thisapp.daemon or not state.enableGUI:
84          logger.info('Clean shutdown complete.')
85          state.thisapp.cleanup()
86          os._exit(0)  # pylint: disable=protected-access
87      else:
88          logger.info('Core shutdown complete.')
89      for thread in threading.enumerate():
90          logger.debug('Thread %s still running', thread.name)