2019-06-03 12:57:09 +00:00
#!/usr/bin/env python3
# coding=utf-8
import json
import os
import subprocess
from threading import Thread
import urllib.parse
import urllib.request
ERRORRMESSAGE = urllib.parse.quote("Bei der Verarbeitung der Daten ist ein Fehler aufgetreten.")
VRE_MANAGER = "http://localhost:5000/vre/jobs"
IMAGES = {
"nlp": "gitlab.ub.uni-bielefeld.de:4567/pjentsch/vre_nlp_node",
"ocr": "gitlab.ub.uni-bielefeld.de:4567/pjentsch/vre_ocr_node"
}
def manage_jobs(service):
# Get queued jobs
2019-06-28 15:45:33 +00:00
queued = json.loads(
urllib.request.urlopen(VRE_MANAGER + "?service=" + service + "&status=queued").read().decode('utf-8')
2019-06-03 12:57:09 +00:00
)
# Return if no jobs are available
if len(queued) == 0:
return
# Get a list of compute nodes
compute_nodes = subprocess.run(
["docker", "ps", "--filter", "ancestor=" + IMAGES[service], "--format", "{{.Names}}"],
stdout=subprocess.PIPE
).stdout.split()
# Filter occupied compute nodes out
compute_nodes = [compute_node for compute_node in compute_nodes if bool(subprocess.run(["docker", "exec", compute_node, "test", "-f", "pyflow.data/active_pyflow_process.txt"]).returncode)]
# Return if no compute nodes are available
if len(compute_nodes) == 0:
return
# Assign jobs to compute nodes
job_assignments = zip(queued, compute_nodes)
for job_assignment in job_assignments:
# Prepare and start the assigned jobs
jobThread = Thread(target=start_job, args=(service, job_assignment[1], job_assignment[0]))
jobThread.start()
def start_job(service, compute_node, job):
# Update job status to "running"
urllib.request.urlopen(
urllib.request.Request(url=VRE_MANAGER + "/" + job["id"] + "?status=running", method="PUT")
)
# Start the service
process = subprocess.run(
["docker", "exec", compute_node, service, "-i", "/root/vre_files/jobs/" + job["id"], "-o", "/root/vre_files/jobs/" + job["id"], "-l", job["language"]],
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL
)
if process.returncode != 0:
urllib.request.urlopen(
urllib.request.Request(url=VRE_MANAGER + "/" + job["id"] + "?status=failed&report=" + ERRORRMESSAGE, method="PUT")
)
return
# Update job status to "finished"
urllib.request.urlopen(
urllib.request.Request(url=VRE_MANAGER + "/" + job["id"] + "?status=finished", method="PUT")
)
# TODO: Send E-Mail to user
manage_jobs("ocr")
manage_jobs("nlp")