fred-oss 0.52.1__tar.gz → 0.54.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. {fred_oss-0.52.1/src/main/fred_oss.egg-info → fred_oss-0.54.0}/PKG-INFO +1 -1
  2. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/_keyval.py +46 -1
  3. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/catalog.py +3 -1
  4. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/interface.py +7 -6
  5. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/_minio.py +3 -3
  6. fred_oss-0.54.0/src/main/fred/version +1 -0
  7. fred_oss-0.54.0/src/main/fred/worker/runner/backend.py +42 -0
  8. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/client.py +27 -7
  9. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/handler.py +6 -4
  10. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/status.py +6 -6
  11. {fred_oss-0.52.1 → fred_oss-0.54.0/src/main/fred_oss.egg-info}/PKG-INFO +1 -1
  12. fred_oss-0.52.1/src/main/fred/version +0 -1
  13. fred_oss-0.52.1/src/main/fred/worker/runner/backend.py +0 -33
  14. {fred_oss-0.52.1 → fred_oss-0.54.0}/MANIFEST.in +0 -0
  15. {fred_oss-0.52.1 → fred_oss-0.54.0}/NOTICE.txt +0 -0
  16. {fred_oss-0.52.1 → fred_oss-0.54.0}/README.md +0 -0
  17. {fred_oss-0.52.1 → fred_oss-0.54.0}/requirements.txt +0 -0
  18. {fred_oss-0.52.1 → fred_oss-0.54.0}/setup.cfg +0 -0
  19. {fred_oss-0.52.1 → fred_oss-0.54.0}/setup.py +0 -0
  20. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/cli/__init__.py +0 -0
  21. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/cli/__main__.py +0 -0
  22. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/cli/interface.py +0 -0
  23. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/cli/main.py +0 -0
  24. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/__init__.py +0 -0
  25. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/__init__.py +0 -0
  26. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/_pubsub.py +0 -0
  27. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/comp/_queue.py +0 -0
  28. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/__init__.py +0 -0
  29. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/_minio.py +0 -0
  30. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/_redis.py +0 -0
  31. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/_stdlib.py +0 -0
  32. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/catalog.py +0 -0
  33. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/interface.py +0 -0
  34. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/dao/service/utils.py +0 -0
  35. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/__init__.py +0 -0
  36. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/callback/__init__.py +0 -0
  37. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/callback/_function.py +0 -0
  38. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/callback/catalog.py +0 -0
  39. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/callback/interface.py +0 -0
  40. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/impl.py +0 -0
  41. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/result.py +0 -0
  42. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/settings.py +0 -0
  43. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/future/utils.py +0 -0
  44. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/__init__.py +0 -0
  45. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/cli_ext.py +0 -0
  46. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/runtime.py +0 -0
  47. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/runtimes/__init__.py +0 -0
  48. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/runtimes/scanner.py +0 -0
  49. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/runtimes/sync.py +0 -0
  50. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/wrappers/__init__.py +0 -0
  51. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/databricks/wrappers/dbutils.py +0 -0
  52. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/runpod/__init__.py +0 -0
  53. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/runpod/cli_ext.py +0 -0
  54. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/integrations/runpod/helper.py +0 -0
  55. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/maturity.py +0 -0
  56. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/monad/__init__.py +0 -0
  57. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/monad/_either.py +0 -0
  58. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/monad/catalog.py +0 -0
  59. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/monad/interface.py +0 -0
  60. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/settings.py +0 -0
  61. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/__init__.py +0 -0
  62. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/dateops.py +0 -0
  63. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imops.py +0 -0
  64. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/__init__.py +0 -0
  65. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/_filesystem.py +0 -0
  66. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/_string.py +0 -0
  67. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/catalog.py +0 -0
  68. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/imout/interface.py +0 -0
  69. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/mlops/__init__.py +0 -0
  70. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/mlops/auto.py +0 -0
  71. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/utils/runtime.py +0 -0
  72. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/version.py +0 -0
  73. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/__init__.py +0 -0
  74. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/interface.py +0 -0
  75. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/__init__.py +0 -0
  76. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/__init__.py +0 -0
  77. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/_handler.py +0 -0
  78. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/_item.py +0 -0
  79. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/_request.py +0 -0
  80. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/_runner_spec.py +0 -0
  81. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/catalog.py +0 -0
  82. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/model/interface.py +0 -0
  83. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/plugins/__init__.py +0 -0
  84. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/plugins/_local.py +0 -0
  85. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/plugins/_runpod.py +0 -0
  86. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/plugins/catalog.py +0 -0
  87. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/plugins/interface.py +0 -0
  88. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/__init__.py +0 -0
  89. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/auth.py +0 -0
  90. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/cli_ext.py +0 -0
  91. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/routers/__init__.py +0 -0
  92. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/routers/_runner.py +0 -0
  93. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/routers/catalog.py +0 -0
  94. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/routers/interface.py +0 -0
  95. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/server.py +0 -0
  96. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/rest/settings.py +0 -0
  97. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/settings.py +0 -0
  98. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/signal.py +0 -0
  99. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/runner/utils.py +0 -0
  100. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred/worker/settings.py +0 -0
  101. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred_oss.egg-info/SOURCES.txt +0 -0
  102. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred_oss.egg-info/dependency_links.txt +0 -0
  103. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred_oss.egg-info/entry_points.txt +0 -0
  104. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred_oss.egg-info/requires.txt +0 -0
  105. {fred_oss-0.52.1 → fred_oss-0.54.0}/src/main/fred_oss.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fred-oss
3
- Version: 0.52.1
3
+ Version: 0.54.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional
2
+ from typing import Iterator, Optional
3
3
 
4
4
  from fred.settings import logger_manager, get_environ_variable
5
5
  from fred.dao.service.catalog import ServiceCatalog
@@ -36,6 +36,51 @@ class FredKeyVal(ComponentInterface):
36
36
  """
37
37
  key: str
38
38
 
39
+ @classmethod
40
+ def keys(cls, pattern: Optional[str] = None, **kwargs) -> Iterator[str]:
41
+ """Returns a list of keys matching the given pattern.
42
+ The implementation of this method depends on the underlying service.
43
+ For example, if the service is Redis, it uses the KEYS command to get the
44
+ list of keys matching the pattern.
45
+ Args:
46
+ pattern (str): The pattern to match keys against. Defaults to "*".
47
+ Returns:
48
+ list[str]: A list of keys matching the pattern.
49
+ Raises:
50
+ NotImplementedError: If the method is not implemented for the current service.
51
+ """
52
+ match cls._cat:
53
+ case ServiceCatalog.REDIS:
54
+ return (
55
+ key if isinstance(key, str) else key.decode("utf-8")
56
+ for key in cls._srv.client.scan_iter(match=pattern, **kwargs)
57
+ )
58
+ case ServiceCatalog.STDLIB:
59
+ import fnmatch
60
+ pattern = pattern or "*"
61
+ return (
62
+ key
63
+ for key in cls._srv.client._memstore_keyval.keys()
64
+ if fnmatch.fnmatch(key, pattern=pattern)
65
+ )
66
+ case ServiceCatalog.MINIO:
67
+ import fnmatch
68
+ pattern = pattern or "*"
69
+ bucket_name = (
70
+ kwargs.get("bucket", None)
71
+ or kwargs.get("minio_bucket", None)
72
+ or get_environ_variable("MINIO_BUCKET")
73
+ )
74
+ if not bucket_name:
75
+ raise ValueError("Missing bucket info to list keys in MinIO service.")
76
+ return (
77
+ key
78
+ for obj in cls._srv.objects(bucket_name, **kwargs)
79
+ if fnmatch.fnmatch((key := obj.object_name), pattern=pattern)
80
+ )
81
+ case _:
82
+ raise NotImplementedError(f"Keys method not implemented for service {cls._nme}")
83
+
39
84
  def set(self, value: str, key: Optional[str] = None, **kwargs) -> None:
40
85
  """Sets a key-value pair in the store.
41
86
  The implementation of this method depends on the underlying service.
@@ -98,7 +98,9 @@ class CompCatalog(enum.Enum):
98
98
  Returns:
99
99
  type[ComponentInterface]: The component class mounted to the specified service.
100
100
  """
101
- return self.value.mount(srv_ref=srv_ref, **kwargs)
101
+ classname_reference = self.value.__name__
102
+ classname_derived = f"{classname_reference}Mounted"
103
+ return type(classname_derived, (self.value,), {}).mount(srv_ref=srv_ref, **kwargs)
102
104
 
103
105
  def auto(self, srv_ref: Optional[SRV_REF_TYPE] = None, **kwargs) -> ComponentInterface:
104
106
  """Automatically creates an instance of the component, mounting it to a service.
@@ -7,6 +7,7 @@ SRV_REF_TYPE = str | ServiceInterface | ServiceCatalog
7
7
 
8
8
  class SrvCompanionMixin:
9
9
  _srv: ServiceInterface
10
+ _cat: ServiceCatalog
10
11
 
11
12
  @classmethod
12
13
  def _set_srv(cls, srv_ref: Optional[SRV_REF_TYPE] = None, **kwargs):
@@ -19,11 +20,16 @@ class SrvCompanionMixin:
19
20
  """
20
21
  match (srv_ref or "REDIS"):
21
22
  case str() as name:
22
- cls._srv = ServiceCatalog[name.upper()].auto(**kwargs)
23
+ cls._cat = ServiceCatalog[name.upper()]
24
+ cls._srv = cls._cat.auto(**kwargs)
23
25
  case ServiceCatalog() as cat:
26
+ cls._cat = cat
24
27
  cls._srv = cat.auto(**kwargs)
25
28
  case ServiceInterface() as instance:
26
29
  cls._srv = instance
30
+ cls._cat = ServiceCatalog.from_classname(
31
+ classname=instance.__class__.__name__
32
+ )
27
33
  case _:
28
34
  raise ValueError(f"Invalid service '{srv_ref}' type: {type(srv_ref)}")
29
35
 
@@ -32,11 +38,6 @@ class SrvCompanionMixin:
32
38
  """Returns the class name of the current service instance."""
33
39
  return self._srv.__class__.__name__
34
40
 
35
- @property
36
- def _cat(self) -> ServiceCatalog:
37
- """Returns the ServiceCatalog enum member corresponding to the current service instance."""
38
- return ServiceCatalog.from_classname(self._nme)
39
-
40
41
 
41
42
  class ComponentInterface(SrvCompanionMixin):
42
43
 
@@ -20,13 +20,13 @@ class OutputMinio(ImageOutputInterface):
20
20
  def out(self, bucket: str, filename: str, presigned: bool = False, **kwargs) -> str:
21
21
  from fred.utils.imops import image_to_b64
22
22
 
23
- image_key = posixpath.join(bucket, filename)
24
23
  image_string = image_to_b64(self.image)
25
- self.client(key=image_key).set(image_string, b64=True, **kwargs)
24
+ self.client(key=filename).set(image_string, b64=True, bucket=bucket, **kwargs)
26
25
  if not presigned:
27
26
  return posixpath.join(
28
27
  self.metadata.get("minio_endpoint", ""),
29
- image_key,
28
+ bucket,
29
+ filename,
30
30
  )
31
31
  # TODO: Implement the generation of a pre-signed URL
32
32
  # https://github.com/minio/minio-py/blob/master/docs/API.md#get_presigned_url
@@ -0,0 +1 @@
1
+ 0.54.0
@@ -0,0 +1,42 @@
1
+ from dataclasses import dataclass
2
+
3
+ from fred.settings import logger_manager
4
+ from fred.dao.comp.catalog import FredKeyVal, FredQueue, CompCatalog
5
+ from fred.dao.service.interface import ServiceInterface
6
+ from fred.dao.service.catalog import ServiceCatalog
7
+
8
+ logger = logger_manager.get_logger(name=__name__)
9
+
10
+
11
+ @dataclass(frozen=True, slots=False)
12
+ class RunnerBackend:
13
+ keyval: FredKeyVal
14
+ queue: FredQueue
15
+ # NOTE: Catalog and service instance references (for internal use)
16
+ # should be a temporal fix until we refactor the backend system
17
+ # according to a more precise usage-patter (still to be defined/identified).
18
+ _cat: ServiceCatalog # Contains complementary service info and simple references
19
+ _srv: ServiceInterface # Allows direct access to a client instance
20
+
21
+ @classmethod
22
+ def auto(cls, service_name: str, **kwargs) -> 'RunnerBackend':
23
+ match (srv_catalog := ServiceCatalog[service_name.upper()]):
24
+ case ServiceCatalog.REDIS:
25
+ from fred.dao.service.utils import get_redis_configs_from_payload
26
+ service_kwargs = get_redis_configs_from_payload(kwargs)
27
+ case ServiceCatalog.STDLIB:
28
+ service_kwargs = {}
29
+ case _:
30
+ logger.error(
31
+ f"Unknown service '{service_name}'... "
32
+ "will attempt to use provided kwargs as-is."
33
+ )
34
+ service_kwargs = kwargs
35
+ logger.info(f"Initializing RunnerBackend using service '{service_name}'")
36
+ srv_instance = srv_catalog.auto(**service_kwargs)
37
+ return cls(
38
+ keyval=CompCatalog.KEYVAL.value.mount(srv_ref=srv_instance),
39
+ queue=CompCatalog.QUEUE.value.mount(srv_ref=srv_instance),
40
+ _cat=srv_catalog,
41
+ _srv=srv_instance,
42
+ )
@@ -61,14 +61,34 @@ class RunnerClient:
61
61
  signal = RunnerSignal[signal.upper()] if isinstance(signal, str) else signal
62
62
  return signal.send(self.req_queue)
63
63
 
64
- def runner_status(self, runner_id: str) -> RunnerStatus:
65
- runner_status=self._runner_backend.keyval(
66
- key=RunnerStatus.get_key(runner_id=runner_id)
67
- )
68
- if not (value := runner_status.get()):
64
+ def runner_info(self, runner_id: str) -> tuple[str, RunnerStatus]:
65
+ runner_status = self._runner_backend.keyval(
66
+ key=RunnerStatus.get_key(runner_id=runner_id)
67
+ )
68
+ if not (out := runner_status.get()):
69
69
  logger.warning(f"No status found for runner_id: '{runner_id}'")
70
- return RunnerStatus.UNDEFINED
71
- return RunnerStatus.parse_value(value=value)
70
+ return ("", RunnerStatus.UNDEFINED)
71
+ return RunnerStatus.parse_value(value=out)
72
+
73
+ def runner_status(self, runner_id: str) -> RunnerStatus:
74
+ _, status = self.runner_info(runner_id=runner_id)
75
+ return status
76
+
77
+ def runner_queue(self, runner_id: str) -> str:
78
+ queue_slug, _ = self.runner_info(runner_id=runner_id)
79
+ return queue_slug
80
+
81
+ def runners(self) -> dict[str, Optional[str]]:
82
+ return {
83
+ key: self._runner_backend.keyval(key=key).get()
84
+ for key in self._runner_backend.keyval.keys(pattern="frd:runner:*")
85
+ }
86
+
87
+ def futures(self) -> dict[str, Optional[str]]:
88
+ return {
89
+ key: self._runner_backend.keyval(key=key).get()
90
+ for key in self._runner_backend.keyval.keys(pattern="frd:future:*:status")
91
+ }
72
92
 
73
93
  def send(
74
94
  self,
@@ -140,9 +140,11 @@ class RunnerHandler(HandlerInterface):
140
140
  runner_status = runner_backend.keyval(
141
141
  key=RunnerStatus.get_key(runner_id=runner_id)
142
142
  )
143
- logger.info(f"Starting runner with ID '{runner_id}' using request-queue '{req_queue.name}'")
143
+ # Start the runner loop in a future and track its status
144
+ on_start_queue_size = req_queue.size()
145
+ logger.info(f"Starting runner '{runner_id}' using req-queue '{req_queue.name}': {on_start_queue_size}")
144
146
  runner_status.set(
145
- value=RunnerStatus.STARTED.get_val(),
147
+ value=RunnerStatus.STARTED.get_val(spec.queue_slug, f"Q({on_start_queue_size})"),
146
148
  expire=None,
147
149
  )
148
150
  runner_loop = Future(
@@ -156,7 +158,7 @@ class RunnerHandler(HandlerInterface):
156
158
  future_id=runner_id,
157
159
  )
158
160
  runner_status.set(
159
- value=RunnerStatus.RUNNING.get_val(),
161
+ value=RunnerStatus.RUNNING.get_val(spec.queue_slug, f"Q({req_queue.size()})"),
160
162
  expire=None,
161
163
  )
162
164
  results = {
@@ -180,7 +182,7 @@ class RunnerHandler(HandlerInterface):
180
182
  }
181
183
  results["pending_requests"] = pending_requests = req_queue.size()
182
184
  runner_status.set(
183
- value=RunnerStatus.STOPPED.get_val(str(pending_requests)),
185
+ value=RunnerStatus.STOPPED.get_val(spec.queue_slug, f"Q({pending_requests})"),
184
186
  expire=3600, # Keep the stopped status for 1 hour
185
187
  )
186
188
  if pending_requests:
@@ -14,14 +14,14 @@ class RunnerStatus(Enum):
14
14
  @staticmethod
15
15
  def get_key(runner_id: str) -> str:
16
16
  """Get the status key for the specified runner ID."""
17
- return f"runner:status:{runner_id}"
17
+ return f"frd:runner:{runner_id}"
18
18
 
19
- def get_val(self, *include) -> str:
19
+ def get_val(self, queue_slug: str, *include) -> str:
20
20
  """Get the string representation of the status."""
21
- return ":".join([self.name, datetime_utcnow().isoformat(), *include])
21
+ return ":".join([queue_slug, self.name, datetime_utcnow().isoformat(), *include])
22
22
 
23
23
  @classmethod
24
- def parse_value(cls, value: str) -> "RunnerStatus":
24
+ def parse_value(cls, value: str) -> tuple[str, "RunnerStatus"]:
25
25
  """Parse the status from the stored value."""
26
- val, *_ = value.split(":")
27
- return cls[val.upper()]
26
+ queue_slug, status, *_ = value.split(":")
27
+ return (queue_slug, cls[status.upper()])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fred-oss
3
- Version: 0.52.1
3
+ Version: 0.54.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -1 +0,0 @@
1
- 0.52.1
@@ -1,33 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- from fred.settings import logger_manager
4
- from fred.dao.comp.catalog import FredKeyVal, FredQueue
5
- from fred.dao.service.catalog import ServiceCatalog
6
-
7
- logger = logger_manager.get_logger(name=__name__)
8
-
9
-
10
- @dataclass(frozen=True, slots=False)
11
- class RunnerBackend:
12
- keyval: FredKeyVal
13
- queue: FredQueue
14
- _cat: ServiceCatalog
15
-
16
- @classmethod
17
- def auto(cls, service_name: str, **kwargs) -> 'RunnerBackend':
18
- service = ServiceCatalog[service_name.upper()]
19
- match service:
20
- case ServiceCatalog.REDIS:
21
- from fred.dao.service.utils import get_redis_configs_from_payload
22
- service_kwargs = get_redis_configs_from_payload(kwargs)
23
- case ServiceCatalog.STDLIB:
24
- service_kwargs = {}
25
- case _:
26
- logger.error(f"Unknown service '{service_name}'... will attempt to use provided kwargs as-is.")
27
- service_kwargs = kwargs
28
- components = service.component_catalog(**service_kwargs)
29
- return cls(
30
- keyval=components.KEYVAL.value,
31
- queue=components.QUEUE.value,
32
- _cat=service,
33
- )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes