• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

docker based ci tool


Commit MetaInfo

修訂b459f117df9e712ec738f76339191854a7ff9a63 (tree)
時間2019-05-31 03:41:46
作者hylom <hylom@user...>
Commiterhylom

Log Message

core-server: use separate thread to run and watch container

Change Summary

差異

--- a/core-server/server.py
+++ b/core-server/server.py
@@ -4,6 +4,9 @@ import os
44 import re
55 import pathlib
66 import time
7+import concurrent.futures
8+import json
9+
710 import grpc
811 from concurrent import futures
912
@@ -19,18 +22,63 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
1922
2023 OUTPUT_DIR = './results'
2124
25+executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
26+
27+def run_task(task_name, task):
28+ print("run task: '{}'".format(task_name))
29+
30+ status = {
31+ "succeeded": False,
32+ "container_status": "Running"
33+ };
34+ reporter = FileReporter(task_name, status)
35+ reporter.write_status()
36+
37+ image = task["image"]
38+ client = docker.from_env()
39+ container = client.containers.run(image=image, detach=True)
40+ container.wait(timeout=task.get("timeout", 60))
41+
42+ print("task done.")
43+
44+ lines = []
45+ for line in container.logs(stream=True):
46+ lines.append(line)
47+ logs = b"".join(lines)
48+
49+ if task.get("auto_remove", True):
50+ container.remove()
51+ print("container removed.")
52+
53+ reporter.set_log(logs)
54+ status["container_status"] = "Done"
55+ reporter.write_status()
56+ reporter.write_log()
57+
58+ print("done.")
59+ return
60+
61+
2262 class FileReporter():
23- def __init__(self, task_name, report, logs):
63+ def __init__(self, task_name, status, log=None):
2464 self.task_name = task_name
25- self.report = report
26- self.logs = logs
65+ self.status = status
66+ self.log = log
2767 self.output_basedir = os.path.join(OUTPUT_DIR, task_name)
68+ self.output_dir = self._get_output_directory()
69+
70+ def set_log(self, log):
71+ self.log = log
2872
29- def write(self):
30- output_dir = self._get_output_directory()
31- log_pathname = output_dir / "logs.txt"
32- with log_pathname.open(mode='wb') as f:
33- f.write(self.logs)
73+ def write_log(self):
74+ pn = self.output_dir / "log.txt"
75+ with pn.open(mode='wb') as f:
76+ f.write(self.log)
77+
78+ def write_status(self):
79+ pn = self.output_dir / "status.json"
80+ with pn.open(mode='w') as f:
81+ json.dump(self.status, f)
3482
3583 def _get_output_directory(self):
3684 if not os.path.exists(self.output_basedir):
@@ -57,12 +105,10 @@ class DockRun(DockRunServicer):
57105 message = "task '{}' not found.".format(req.task_name)
58106 return RunTaskReply(is_succeed=False, message=message)
59107
60- logs = self._run_task(task)
61- report = {
62- "succeed": True,
63- };
64- reporter = FileReporter(req.task_name, report, logs)
65- reporter.write()
108+ # generate process
109+ #self._run_task(task)
110+ executor.submit(run_task, req.task_name, task)
111+
66112 return RunTaskReply(is_succeed=True, message="")
67113
68114 def _run_task(self, task):
@@ -79,7 +125,15 @@ class DockRun(DockRunServicer):
79125 if task.get("auto_remove", True):
80126 container.remove()
81127
82- return logs
128+ report = {
129+ "succeeded": False,
130+ "status": None,
131+ };
132+
133+ reporter = FileReporter(req.task_name, report, logs)
134+ reporter.write()
135+
136+ return
83137
84138 def main():
85139 server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))