indexify 0.3.6__tar.gz → 0.3.8__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 (24) hide show
  1. {indexify-0.3.6 → indexify-0.3.8}/PKG-INFO +2 -2
  2. {indexify-0.3.6 → indexify-0.3.8}/pyproject.toml +2 -2
  3. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/cli/cli.py +12 -4
  4. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/executor.py +3 -0
  5. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/server/function_executor_server_factory.py +2 -1
  6. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/server/subprocess_function_executor_server_factory.py +2 -0
  7. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/single_task_runner.py +3 -0
  8. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/task_reporter.py +9 -0
  9. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/task_runner.py +10 -0
  10. {indexify-0.3.6 → indexify-0.3.8}/README.md +0 -0
  11. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/README.md +0 -0
  12. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/api_objects.py +0 -0
  13. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/downloader.py +0 -0
  14. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/function_executor.py +0 -0
  15. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/function_executor_state.py +0 -0
  16. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/health_checker.py +0 -0
  17. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/invocation_state_client.py +0 -0
  18. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/server/client_configuration.py +0 -0
  19. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/server/function_executor_server.py +0 -0
  20. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/server/subprocess_function_executor_server.py +0 -0
  21. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/task_input.py +0 -0
  22. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/function_executor/task_output.py +0 -0
  23. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/runtime_probes.py +0 -0
  24. {indexify-0.3.6 → indexify-0.3.8}/src/indexify/executor/task_fetcher.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: indexify
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: Open Source Indexify components and helper tools
5
5
  Home-page: https://github.com/tensorlakeai/indexify
6
6
  License: Apache 2.0
@@ -22,7 +22,7 @@ Requires-Dist: pydantic (==2.10.4)
22
22
  Requires-Dist: pyyaml (>=6,<7)
23
23
  Requires-Dist: rich (>=13.9.2,<14.0.0)
24
24
  Requires-Dist: structlog (>=24.4.0,<25.0.0)
25
- Requires-Dist: tensorlake (>=0.1.13)
25
+ Requires-Dist: tensorlake (>=0.1.16)
26
26
  Requires-Dist: typer (>=0.12,<0.13)
27
27
  Project-URL: Repository, https://github.com/tensorlakeai/indexify
28
28
  Description-Content-Type: text/markdown
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "indexify"
3
3
  # Incremented if any of the components provided in this packages are updated.
4
- version = "0.3.6"
4
+ version = "0.3.8"
5
5
  description = "Open Source Indexify components and helper tools"
6
6
  authors = ["Tensorlake Inc. <support@tensorlake.ai>"]
7
7
  license = "Apache 2.0"
@@ -24,7 +24,7 @@ grpcio = "1.70.0"
24
24
  pydantic = "2.10.4"
25
25
  httpx-sse = "^0.4.0"
26
26
  # Adds function-executor binary and utils lib.
27
- tensorlake = ">=0.1.13"
27
+ tensorlake = ">=0.1.16"
28
28
 
29
29
  # CLI only
30
30
  rich = "^13.9.2"
@@ -34,8 +34,6 @@ from indexify.executor.function_executor.server.subprocess_function_executor_ser
34
34
  SubprocessFunctionExecutorServerFactory,
35
35
  )
36
36
 
37
- logger = structlog.get_logger(module=__name__)
38
-
39
37
  custom_theme = Theme(
40
38
  {
41
39
  "info": "cyan",
@@ -208,6 +206,13 @@ def executor(
208
206
  ports: Tuple[int, int] = typer.Option(
209
207
  (50000, 51000), help="Range of localhost TCP ports to be used by the executor"
210
208
  ),
209
+ disable_automatic_function_executor_management: Annotated[
210
+ bool,
211
+ typer.Option(
212
+ "--disable-automatic-function-executor-management",
213
+ help="Disable automatic Function Executor management by Executor",
214
+ ),
215
+ ] = False,
211
216
  ):
212
217
  if dev:
213
218
  configure_development_mode_logging()
@@ -218,18 +223,20 @@ def executor(
218
223
  "At least one function must be specified when not running in development mode"
219
224
  )
220
225
 
221
- id = nanoid.generate()
222
226
  executor_version = version("indexify")
227
+ id = nanoid.generate()
228
+ logger = structlog.get_logger(module=__name__, executor_id=id)
229
+
223
230
  logger.info(
224
231
  "starting executor",
225
232
  server_addr=server_addr,
226
233
  config_path=config_path,
227
- executor_id=id,
228
234
  executor_version=executor_version,
229
235
  executor_cache=executor_cache,
230
236
  ports=ports,
231
237
  functions=function_uris,
232
238
  dev_mode=dev,
239
+ disable_automatic_function_executor_management=disable_automatic_function_executor_management,
233
240
  )
234
241
 
235
242
  executor_cache = Path(executor_cache).expanduser().absolute()
@@ -258,6 +265,7 @@ def executor(
258
265
  development_mode=dev,
259
266
  server_ports=range(ports[0], ports[1]),
260
267
  ),
268
+ disable_automatic_function_executor_management=disable_automatic_function_executor_management,
261
269
  ).run()
262
270
 
263
271
 
@@ -27,6 +27,7 @@ class Executor:
27
27
  function_executor_server_factory: FunctionExecutorServerFactory,
28
28
  server_addr: str = "localhost:8900",
29
29
  config_path: Optional[str] = None,
30
+ disable_automatic_function_executor_management: bool = False,
30
31
  ):
31
32
  self._logger = structlog.get_logger(module=__name__)
32
33
  self._is_shutdown: bool = False
@@ -40,9 +41,11 @@ class Executor:
40
41
  self._base_url = f"{protocol}://{self._server_addr}"
41
42
  self._code_path = code_path
42
43
  self._task_runner = TaskRunner(
44
+ executor_id=id,
43
45
  function_executor_server_factory=function_executor_server_factory,
44
46
  base_url=self._base_url,
45
47
  config_path=config_path,
48
+ disable_automatic_function_executor_management=disable_automatic_function_executor_management,
46
49
  )
47
50
  self._downloader = Downloader(
48
51
  code_path=code_path, base_url=self._base_url, config_path=config_path
@@ -14,7 +14,8 @@ class FunctionExecutorServerConfiguration:
14
14
  configuration parameters or raise an exception if it can't implement
15
15
  them."""
16
16
 
17
- def __init__(self, image_uri: Optional[str]):
17
+ def __init__(self, executor_id: str, image_uri: Optional[str]):
18
+ self.executor_id: str = executor_id
18
19
  # Container image URI of the Function Executor Server.
19
20
  self.image_uri: Optional[str] = image_uri
20
21
 
@@ -28,6 +28,8 @@ class SubprocessFunctionExecutorServerFactory(FunctionExecutorServerFactory):
28
28
  try:
29
29
  port = self._allocate_port()
30
30
  args = [
31
+ "--executor-id",
32
+ config.executor_id,
31
33
  "--address",
32
34
  _server_address(port),
33
35
  ]
@@ -25,6 +25,7 @@ from .task_output import TaskOutput
25
25
  class SingleTaskRunner:
26
26
  def __init__(
27
27
  self,
28
+ executor_id: str,
28
29
  function_executor_state: FunctionExecutorState,
29
30
  task_input: TaskInput,
30
31
  function_executor_server_factory: FunctionExecutorServerFactory,
@@ -32,6 +33,7 @@ class SingleTaskRunner:
32
33
  config_path: Optional[str],
33
34
  logger: Any,
34
35
  ):
36
+ self._executor_id: str = executor_id
35
37
  self._state: FunctionExecutorState = function_executor_state
36
38
  self._task_input: TaskInput = task_input
37
39
  self._factory: FunctionExecutorServerFactory = function_executor_server_factory
@@ -76,6 +78,7 @@ class SingleTaskRunner:
76
78
  )
77
79
  config: FunctionExecutorServerConfiguration = (
78
80
  FunctionExecutorServerConfiguration(
81
+ executor_id=self._executor_id,
79
82
  image_uri=self._task_input.task.image_uri,
80
83
  )
81
84
  )
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import time
2
3
  from typing import Any, List, Optional, Tuple
3
4
 
4
5
  import nanoid
@@ -74,10 +75,18 @@ class TaskReporter:
74
75
  ),
75
76
  "files": output_files if len(output_files) > 0 else FORCE_MULTIPART,
76
77
  }
78
+
79
+ start_time = time.time()
77
80
  # Run in a separate thread to not block the main event loop.
78
81
  response = await asyncio.to_thread(
79
82
  self._client.post, url=f"{self._base_url}/internal/ingest_files", **kwargs
80
83
  )
84
+ end_time = time.time()
85
+ logger.info(
86
+ "task_outcome_reported",
87
+ response_time=end_time - start_time,
88
+ response_code=response.status_code,
89
+ )
81
90
 
82
91
  try:
83
92
  response.raise_for_status()
@@ -18,13 +18,19 @@ class TaskRunner:
18
18
 
19
19
  def __init__(
20
20
  self,
21
+ executor_id: str,
21
22
  function_executor_server_factory: FunctionExecutorServerFactory,
22
23
  base_url: str,
23
24
  config_path: Optional[str],
25
+ disable_automatic_function_executor_management: bool,
24
26
  ):
27
+ self._executor_id: str = executor_id
25
28
  self._factory: FunctionExecutorServerFactory = function_executor_server_factory
26
29
  self._base_url: str = base_url
27
30
  self._config_path: Optional[str] = config_path
31
+ self._disable_automatic_function_executor_management: bool = (
32
+ disable_automatic_function_executor_management
33
+ )
28
34
  # The fields below are protected by the lock.
29
35
  self._lock: asyncio.Lock = asyncio.Lock()
30
36
  self._is_shutdown: bool = False
@@ -71,6 +77,9 @@ class TaskRunner:
71
77
  # - Each Function Executor rans at most 1 task concurrently.
72
78
  await state.wait_running_tasks_less(1)
73
79
 
80
+ if self._disable_automatic_function_executor_management:
81
+ return # Disable Function Executor destroy in manual management mode.
82
+
74
83
  if state.function_id_with_version != _function_id_with_version(task):
75
84
  await state.destroy_function_executor()
76
85
  state.function_id_with_version = _function_id_with_version(task)
@@ -81,6 +90,7 @@ class TaskRunner:
81
90
  self, state: FunctionExecutorState, task_input: TaskInput, logger: Any
82
91
  ) -> TaskOutput:
83
92
  runner: SingleTaskRunner = SingleTaskRunner(
93
+ executor_id=self._executor_id,
84
94
  function_executor_state=state,
85
95
  task_input=task_input,
86
96
  function_executor_server_factory=self._factory,
File without changes