ailab/benchmark/db_controller.py (130 lines of code) (raw):

from __future__ import absolute_import, division, print_function, unicode_literals from benchmark.models import BenchmarkInfo, Device from django.utils import timezone def get_payload(req): action = req.get("action") identifier = req.get("identifier") benchmarks = req.get("benchmarks") ids_str = req.get("ids") id = req.get("id") claimer = req.get("claimer") result = req.get("result") devices_str = req.get("devices") user = req.get("user") job_queue = req.get("job_queue") assert action is not None, "action not provided" devices = [] if devices_str is not None: devices = devices_str.split(",") if len(devices) == 1: if devices[0] == "": devices = [] ids = [] if ids_str is None and (action == "run" or action == "release"): raise AssertionError("ids must be specified for {}".format(action)) elif ids_str is not None: ids = ids_str.split(",") if action == "add": for device in devices: r = BenchmarkInfo( status="QUEUE", identifier=identifier, benchmarks=benchmarks, device=device, user=user, job_queue=job_queue, ) r.save() return {"status": "success"} elif action == "claim": for device in devices: queryset = BenchmarkInfo.objects.filter( status="CLAIMED", device=device, claimer=claimer, job_queue=job_queue ) if not queryset: queryset = BenchmarkInfo.objects.filter( status="QUEUE", device=device, job_queue=job_queue ) if queryset: r = queryset[0] r.status = "CLAIMED" r.claimed_time = timezone.now() r.claimer = claimer r.save() Device.objects.filter(device__in=devices).update(heartbeat_time=timezone.now()) queryset = BenchmarkInfo.objects.filter(status="CLAIMED", claimer=claimer) return {"status": "success", "values": list(queryset.values())} elif action == "run": BenchmarkInfo.objects.filter( id__in=ids, claimer=claimer, job_queue=job_queue ).update(status="RUNNING", start_time=timezone.now()) return {"status": "success"} elif action == "release": BenchmarkInfo.objects.filter(id__in=ids, job_queue=job_queue).update( status="QUEUE", claimed_time=None, start_time=None, claimer=None ) return {"status": "success"} elif action == "done": assert id is not None, "id must be specified for " + action log = req.get("log") assert log is not None, "Log field is empty" status = req.get("status") assert status == "DONE" or status == "FAILED" or status == "USER_ERROR", ( "Unknown status " + status ) BenchmarkInfo.objects.filter(id=id, job_queue=job_queue).update( status=status, done_time=timezone.now(), result=result, log=log ) return {"status": "success"} elif action == "status": queryset = BenchmarkInfo.objects.filter( identifier=identifier, job_queue=job_queue ) return { "status": "success", "values": list(queryset.values("status", "id", "device")), } elif action == "get": queryset = BenchmarkInfo.objects.filter(id__in=ids, job_queue=job_queue) return {"status": "success", "values": list(queryset.values())} elif action == "list_devices": # Two options: (1) If job_queue=*, it will query all non DISABLED devices; # (2) Otherwise, it will query non DISABLED devices from the specified # job_queue. queryset = Device.objects.exclude(status="DISABLED") if job_queue != "*": queryset = Device.objects.filter(job_queue=job_queue) return {"status": "success", "values": list(queryset.values())} elif action == "update_devices": reset = req.get("reset") if reset == "true": Device.objects.filter(claimer=claimer).update( status="DISABLED", update_time=timezone.now() ) for device in devices: d = device.split("|") assert len(d) == 3, "Must have three elements in the input" data = { "device": d[0], "hash": d[1], "status": "OCCUPIED" if d[2] == "0" else "AVAILABLE" if d[2] == "1" else "OFFLINE", "claimer": claimer, "job_queue": job_queue, } defaults = { "device": data["device"], "status": data["status"], "claimer": data["claimer"], "job_queue": data["job_queue"], "update_time": timezone.now(), "heartbeat_time": timezone.now(), } obj, created = Device.objects.update_or_create( hash=data["hash"], defaults=defaults, ) obj.save() return {"status": "success"} else: raise AssertionError("action {} not recognized".format(action))