You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.0 KiB

  1. import pathlib as pl
  2. import json
  3. import os
  4. import multiprocessing
  5. import threading
  6. from . import batch
  7. class Plan:
  8. def __init__(self, experiment=None, lock=None):
  9. self.experiment = None
  10. self.file = None
  11. self.pending_instances = []
  12. self.assigned_instances = []
  13. self.__lock = threading.Lock() if lock == None else lock
  14. if experiment:
  15. self.create(experiment)
  16. def create(self, experiment):
  17. self.experiment = pl.Path(experiment).resolve()
  18. self.__set_file()
  19. if self.__is_finished():
  20. self.__create()
  21. else:
  22. self.__load()
  23. def __create(self):
  24. with open(self.experiment, "r") as expf:
  25. exp_obj = json.loads(expf.read())
  26. instances = batch.load(pl.Path(exp_obj["batch"]).resolve())
  27. self.pending_instances = instances
  28. self.__update_file()
  29. def __set_file(self):
  30. if self.experiment == None:
  31. self.file = None
  32. else:
  33. exp_path = pl.Path(self.experiment)
  34. self.file = exp_path.parent / (exp_path.stem + ".plan")
  35. def __load(self):
  36. self.pending_instances = []
  37. self.assigned_instances = []
  38. if not self.file.is_file():
  39. return
  40. with open(self.file, "r") as pfile:
  41. content = json.loads(pfile.read())
  42. if "assigned" in content:
  43. self.assigned_instances = content["assigned"]
  44. if "pending" in content:
  45. self.pending_instances = content["pending"]
  46. def __is_finished(self):
  47. return False if self.file.is_file() else True
  48. def next(self):
  49. with self.__lock:
  50. self.__load()
  51. if len(self.pending_instances) == 0:
  52. return None
  53. next_instance = self.pending_instances.pop()
  54. self.assigned_instances.append(next_instance)
  55. self.__update_file()
  56. return next_instance
  57. def done_with(self, instance):
  58. with self.__lock:
  59. self.__load()
  60. if instance in self.assigned_instances:
  61. self.assigned_instances.remove(instance)
  62. self.__update_file()
  63. def __update_file(self):
  64. content = {}
  65. if len(self.assigned_instances) > 0:
  66. content["assigned"] = list(map(str, self.assigned_instances))
  67. if len(self.pending_instances) > 0:
  68. content["pending"] = list(map(str, self.pending_instances))
  69. if content:
  70. with open(self.file, "w") as pfile:
  71. pfile.write(json.dumps(content))
  72. elif self.file.is_file():
  73. self.file.unlink()
  74. #def __del__(self):
  75. def delete(self):
  76. with self.__lock:
  77. self.__load()
  78. self.pending_instances.extend(self.assigned_instances)
  79. self.assigned_instances = []
  80. self.__update_file()