Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

192 Zeilen
4.6 KiB

  1. """
  2. Simple Scheduler
  3. This scheduler is used to fire events across multiple databases. A database
  4. master_scheduler is maintained with one event and one log table
  5. Events are added by different databases in the master scheduler using the
  6. `set_event` method and they are executed by the cron.
  7. __main__ will call run
  8. To install:
  9. -----------
  10. python install_lib.py [root] [password] master_scheduler
  11. In cron:
  12. --------
  13. python [path]webnotes/utils/scheduler.py
  14. """
  15. class Scheduler:
  16. def connect(self):
  17. """
  18. Connect to the 'master_schduler' database
  19. """
  20. if hasattr(self,'conn'): return
  21. import webnotes.defs, webnotes.db
  22. pwd = webnotes.defs.__dict__.get('scheduler_password')
  23. if pwd==None: pwd = webnotes.defs.db_password
  24. self.conn = webnotes.db.Database(user='master_scheduler',password=pwd)
  25. def set(self, event, interval, recurring, db_name=None):
  26. """
  27. Add an event to the Event table in the master scheduler
  28. """
  29. self.connect()
  30. if not db_name:
  31. import webnotes
  32. db_name = webnotes.conn.cur_db_name
  33. self.clear(db_name, event)
  34. self.conn.sql("start transaction")
  35. self.conn.sql("""insert into
  36. Event (`db_name`, `event`, `interval`, next_execution, recurring)
  37. values (%s, %s, %s, ADDTIME(NOW(), SEC_TO_TIME(%s)), %s)
  38. """, (webnotes.conn.cur_db_name, event, interval, interval, recurring))
  39. self.conn.sql("commit")
  40. def get_events(self, db_name=None):
  41. """
  42. Returns list of upcoming events
  43. """
  44. self.connect()
  45. if not db_name:
  46. import webnotes
  47. db_name = webnotes.conn.cur_db_name
  48. return self.conn.sql("select * from Event where db_name=%s", db_name, as_dict=1)
  49. def get_log(self, db_name=None):
  50. """
  51. Returns log of events
  52. """
  53. self.connect()
  54. if not db_name:
  55. import webnotes
  56. db_name = webnotes.conn.cur_db_name
  57. return self.conn.sql("select * from EventLog where db_name=%s limit 50", db_name, as_dict=1)
  58. def clear(self, db_name, event):
  59. """
  60. Clears the event
  61. """
  62. self.conn.sql("start transaction")
  63. self.conn.sql("delete from Event where `event`=%s and db_name=%s", (event, db_name))
  64. self.conn.sql("commit")
  65. def execute(self, db_name, event, now):
  66. """
  67. Executes event in the specifed db
  68. """
  69. import webnotes, webnotes.defs, webnotes.db
  70. try:
  71. webnotes.conn = None
  72. webnotes.conn = webnotes.db.Database(user=db_name, password=webnotes.get_db_password(db_name))
  73. webnotes.session = {'user':'Administrator'}
  74. module = '.'.join(event.split('.')[:-1])
  75. method = event.split('.')[-1]
  76. exec 'from %s import %s' % (module, method)
  77. webnotes.conn.begin()
  78. ret = locals()[method]()
  79. webnotes.conn.commit()
  80. webnotes.conn.close()
  81. self.log(db_name, event, ret or 'Ok')
  82. except Exception, e:
  83. if now:
  84. print webnotes.getTraceback()
  85. else:
  86. self.log(db_name, event, webnotes.getTraceback())
  87. def log(self, db_name, event, traceback):
  88. """
  89. Log an event error
  90. """
  91. self.conn.sql("start transaction")
  92. self.conn.sql("insert into `EventLog`(db_name, event, log, executed_on) values (%s, %s, %s, now())", \
  93. (db_name, event, traceback))
  94. # delete old logs
  95. self.conn.sql("delete from EventLog where executed_on < subdate(curdate(), interval 30 day)")
  96. self.conn.sql("commit")
  97. def run(self, now=0):
  98. """
  99. Run scheduled (due) events and reset time for recurring events
  100. """
  101. cond = ''
  102. if not now:
  103. cond = 'where next_execution < NOW()'
  104. el = self.conn.sql("""select `db_name`, `event`, `recurring`, `interval`
  105. from `Event`
  106. %s""" % cond, as_dict=1)
  107. for e in el:
  108. # execute the event
  109. self.execute(e['db_name'], e['event'], now)
  110. # if recurring, update next_execution
  111. if e['recurring']:
  112. self.conn.sql("start transaction")
  113. self.conn.sql("update Event set next_execution = addtime(now(), sec_to_time(%s)) where event=%s", (e['interval'], e['event']))
  114. self.conn.sql("commit")
  115. # else clear
  116. else:
  117. self.clear(e['db_name'], e['event'])
  118. def set_event(event, interval=60*60*24, recurring=1):
  119. """
  120. Adds an event to the master scheduler
  121. """
  122. sch = Scheduler()
  123. sch.connect()
  124. return sch.set(event, interval, recurring)
  125. def cancel_event(event):
  126. """
  127. Cancels an event
  128. """
  129. import webnotes
  130. sch = Scheduler()
  131. sch.connect()
  132. return sch.clear(webnotes.conn.cur_db_name, event)
  133. # to be called from cron
  134. if __name__=='__main__':
  135. import os,sys
  136. cgi_bin_path = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-3])
  137. sys.path.append(cgi_bin_path)
  138. import webnotes
  139. import webnotes.defs
  140. sys.path.append(getattr(webnotes.defs,'modules_path',None))
  141. sch = Scheduler()
  142. sch.connect()
  143. if len(sys.argv) > 1 and sys.argv[1]=='run':
  144. sch.run(now=1)
  145. else:
  146. sch.run()