daemon.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import os
  2. import traceback
  3. import threading
  4. import pymysql
  5. import time
  6. import subprocess
  7. GAP = 2
  8. def execute(s):
  9. print('Running: ', s)
  10. try:
  11. subprocess.run(s, shell=True, check=True)
  12. except subprocess.CalledProcessError as e:
  13. raise Exception('Failed to execute the command')
  14. def watch_stream():
  15. db = pymysql.connect(host='uoj-db', user='root', password='root', database='app_uoj233')
  16. db.autocommit(True)
  17. with open('did', 'r') as f:
  18. did = int(f.read().strip())
  19. print(f'Watching request id {did}')
  20. last = ''
  21. curs = db.cursor()
  22. curs.execute('insert ignore into datum_streams (id) values (%s)', (did, ))
  23. while True:
  24. if not os.path.exists('stream'):
  25. continue
  26. with open('stream', 'r') as f:
  27. d = f.read()
  28. if last == d:
  29. if open('flag').read() == 'done':
  30. print('Finished!')
  31. return
  32. continue
  33. curs = db.cursor()
  34. curs.execute('update datum_streams set stream = %s where id = %s', (d, did))
  35. last = d
  36. time.sleep(GAP)
  37. def generate_data_zip(p, stat):
  38. watcher = threading.Thread(target=watch_stream)
  39. open('flag', 'w').write('no')
  40. open('did', 'w').write('')
  41. open('stream', 'w').write('')
  42. did, pid, std, timelim, memlim = p
  43. print(f'Received request for problem {pid}')
  44. with open('stat.md', 'w') as f:
  45. f.write(stat)
  46. with open('std.cpp', 'w') as f:
  47. f.write(std)
  48. with open('did', 'w') as f:
  49. print(did, file=f)
  50. watcher.start()
  51. execute(f'sudo -u datum python3 datum.py stat.md --time {timelim} --mem {memlim}')
  52. open('flag', 'w').write('done')
  53. watcher.join()
  54. open('flag', 'w').write('no')
  55. open('did', 'w').write('')
  56. open('stream', 'w').write('')
  57. def move_to_upload(pid):
  58. execute(f'rm -r /var/uoj_data/web/data/upload/{pid} || true')
  59. execute(f'mkdir /var/uoj_data/web/data/upload/{pid} || true')
  60. execute(f'mv data.zip /var/uoj_data/web/data/upload/{pid}/')
  61. execute(f'cd /var/uoj_data/web/data/upload/{pid}/; unzip data.zip; rm data.zip')
  62. if __name__ == '__main__':
  63. db = pymysql.connect(host='uoj-db', user='root', password='root', database='app_uoj233')
  64. db.autocommit(True)
  65. while True:
  66. curs = db.cursor()
  67. curs.execute('select id, pid, std, timelimit, memlimit from datum_requests where status = "Waiting" order by id asc limit 1')
  68. res = curs.fetchall()
  69. if not res:
  70. time.sleep(GAP)
  71. continue
  72. curs = db.cursor()
  73. curs.execute(f'update datum_requests set status = "Generating" where id = {res[0][0]}')
  74. db.commit()
  75. curs = db.cursor()
  76. curs.execute(f'select statement_md from problems_contents where id = {res[0][1]}')
  77. try:
  78. generate_data_zip(res[0], curs.fetchall()[0][0])
  79. move_to_upload(res[0][1])
  80. except Exception as e:
  81. print(f'Exception {e}')
  82. traceback.print_exc()
  83. curs = db.cursor()
  84. curs.execute(f'update datum_requests set status = "Failed" where id = {res[0][0]}')
  85. curs.execute(f'update datum_requests set finish_time = now() where id = {res[0][0]}')
  86. db.commit()
  87. print(f'Failed {res[0][0]}')
  88. else:
  89. curs = db.cursor()
  90. generator = open('gen.py', 'r').read()
  91. curs.execute(f'update datum_requests set status = "Done" where id = {res[0][0]}')
  92. curs.execute('update datum_requests set generator = %s where id = %s', (generator, res[0][0]))
  93. curs.execute(f'update datum_requests set finish_time = now() where id = {res[0][0]}')
  94. db.commit()
  95. print(f'Done {res[0][0]}')