数据库的封装与处理
mport time
import config
import MySQLdb
import logging
import types
def run_sql(sql):
'''执行sql语句,并返回结果'''
con = None
while True:
try:
con = MySQLdb.connect(config.db_host,config.db_user,config.db_password,
config.db_name,charset=config.db_charset)
break
except:
logging.error('Cannot connect to database,trying again')
time.sleep(1)
cur = con.cursor()
try:
if type(sql) == types.StringType:
cur.execute(sql)
elif type(sql) == types.ListType:
for i in sql:
cur.execute(i)
except MySQLdb.OperationalError,e:
logging.error(e)
cur.close()
con.close()
return False
con.commit()
data = cur.fetchall()
cur.close()
con.close()
return data
def run_sql_without_return(sql):
'''执行sql语句,不返回结果'''
con = None
while True:
try:
con = MySQLdb.connect(config.db_host,config.db_user,config.db_password,
config.db_name,charset=config.db_charset)
break
except:
logging.error('Cannot connect to database,trying again')
time.sleep(1)
cur = con.cursor()
try:
if type(sql) == types.StringType:
cur.execute(sql)
elif type(sql) == types.ListType:
for i in sql:
cur.execute(i)
except MySQLdb.OperationalError,e:
logging.error(e)
cur.close()
con.close()
return False
con.commit()
cur.close()
con.close()
return True
生产者:循环扫描数据库
def put_task_into_queue():
'''循环扫描数据库,将任务添加到队列'''
while True:
q.join() # 阻塞程序,直到队列里面的任务全部完成
# 删除时间超过 1天 的数据。
delete_sql = "delete from judgeOL_submitcode where `submit_date` < date_sub(now(), interval 1 day)"
run_sql(delete_sql)
# 找出所有等待处理的数据
sql = "select id,language,submit_code_text,problem_id,user_id from judgeOL_submitcode " \
"where status='Waiting' order by submit_date DESC"
# 返回数据库类型的数据
data = run_sql(sql)
time.sleep(0.2) # 延时0.2秒,防止因速度太快不能获取代码
for i in data:
solution_id, language, submit_code_text, problem_id, user_id = i
logging.info("The language is : "+ language)
dblock.acquire()
ret = get_code(solution_id, problem_id, language)
dblock.release()
if ret == False:
# 防止因速度太快不能获取代码
time.sleep(0.5)
dblock.acquire()
ret = get_code(solution_id, problem_id, language)
logging.info("The SECOND get the code is"+str(ret))
dblock.release()
if ret == False:
dblock.acquire()
logging.info("The THIRD failure!")
update_solution_status(solution_id, "System Error")
dblock.release()
# 清理暂时进行代码处理的文件夹
clean_work_dir(solution_id)
continue
task = {
"solution_id": solution_id,
"problem_id": problem_id,
"submit_code_text": submit_code_text,
"user_id": user_id,
"language": language,
}
q.put(task)
dblock.acquire()
update_solution_status(solution_id, "Judging")
dblock.release()
time.sleep(0.5)
消费者:取出数据进行处理
def worker():
'''工作线程,循环扫描队列,获得评判任务并执行'''
while True:
if q.empty() is True: # 队列为空,空闲
logging.info("%s idle" % (threading.current_thread().name))
task = q.get() # 获取任务,如果队列为空则阻塞
solution_id = task['solution_id']
problem_id = task['problem_id']
language = task['language']
user_id = task['user_id']
data_count = get_data_count(task['problem_id']) # 获取测试数据的个数
logging.info("judging %s" % solution_id)
result = run(
problem_id,
solution_id,
language,
data_count,
user_id,
dblock) # 评判
logging.info(
"%s result %s" % (
result[
'solution_id'],
result[
'result']))
dblock.acquire()
update_result(task,result) # 将结果写入数据库
dblock.release()
if config.auto_clean: # 清理work目录
clean_work_dir(result['solution_id'])
q.task_done() # 一个任务完成