indexify 0.3.3__tar.gz → 0.3.4__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.
- {indexify-0.3.3 → indexify-0.3.4}/PKG-INFO +3 -3
- {indexify-0.3.3 → indexify-0.3.4}/pyproject.toml +3 -3
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/function_executor.py +18 -0
- indexify-0.3.4/src/indexify/executor/function_executor/health_checker.py +79 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/single_task_runner.py +31 -3
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/configuration.py +3 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor.proto +8 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2.py +7 -3
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2.pyi +10 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2_grpc.py +47 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/service.py +11 -0
- {indexify-0.3.3 → indexify-0.3.4}/README.md +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/cli/cli.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/README.md +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/api_objects.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/downloader.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/executor.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/function_executor_state.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/invocation_state_client.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/server/function_executor_server.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/server/function_executor_server_factory.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/server/subprocess_function_executor_server.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/server/subprocess_function_executor_server_factory.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/task_input.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/task_output.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/runtime_probes.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/task_fetcher.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/task_reporter.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/task_runner.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/README.md +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/handlers/run_function/function_inputs_loader.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/handlers/run_function/handler.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/handlers/run_function/request_validator.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/handlers/run_function/response_helper.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/initialize_request_validator.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/invocation_state/invocation_state_proxy_server.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/invocation_state/proxied_invocation_state.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/invocation_state/response_validator.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/main.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/message_validator.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/server.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/utils/README.md +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/utils/http_client.py +0 -0
- {indexify-0.3.3 → indexify-0.3.4}/src/indexify/utils/logging.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: indexify
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.4
|
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
|
@@ -17,13 +17,13 @@ Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Requires-Dist: grpcio (==1.68.1)
|
18
18
|
Requires-Dist: grpcio-tools (==1.68.1)
|
19
19
|
Requires-Dist: httpx-sse (>=0.4.0,<0.5.0)
|
20
|
-
Requires-Dist: httpx[http2] (>=0.
|
20
|
+
Requires-Dist: httpx[http2] (>=0.27,<0.28)
|
21
21
|
Requires-Dist: nanoid (>=2.0.0,<3.0.0)
|
22
22
|
Requires-Dist: pydantic (==2.10.4)
|
23
23
|
Requires-Dist: pyyaml (>=6,<7)
|
24
24
|
Requires-Dist: rich (>=13.9.2,<14.0.0)
|
25
25
|
Requires-Dist: structlog (>=24.4.0,<25.0.0)
|
26
|
-
Requires-Dist: tensorlake (>=0.1.
|
26
|
+
Requires-Dist: tensorlake (>=0.1.9)
|
27
27
|
Requires-Dist: typer (>=0.12,<0.13)
|
28
28
|
Project-URL: Repository, https://github.com/tensorlakeai/indexify
|
29
29
|
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.
|
4
|
+
version = "0.3.4"
|
5
5
|
description = "Open Source Indexify components and helper tools"
|
6
6
|
authors = ["Tensorlake Inc. <support@tensorlake.ai>"]
|
7
7
|
license = "Apache 2.0"
|
@@ -18,12 +18,12 @@ function-executor = "indexify.function_executor.main:main"
|
|
18
18
|
python = "^3.9"
|
19
19
|
structlog = "^24.4.0"
|
20
20
|
pyyaml = "^6"
|
21
|
-
httpx = { version = "^0.
|
21
|
+
httpx = { version = "^0.27", extras = ["http2"] }
|
22
22
|
grpcio = "1.68.1"
|
23
23
|
|
24
24
|
# Function Executor only
|
25
25
|
grpcio-tools = "1.68.1"
|
26
|
-
tensorlake = "
|
26
|
+
tensorlake = ">=0.1.9"
|
27
27
|
|
28
28
|
# Executor only
|
29
29
|
pydantic = "2.10.4"
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/function_executor.py
RENAMED
@@ -12,6 +12,7 @@ from indexify.function_executor.proto.function_executor_pb2_grpc import (
|
|
12
12
|
)
|
13
13
|
from indexify.utils.http_client import get_httpx_client
|
14
14
|
|
15
|
+
from .health_checker import HealthChecker
|
15
16
|
from .invocation_state_client import InvocationStateClient
|
16
17
|
from .server.function_executor_server import (
|
17
18
|
FUNCTION_EXECUTOR_SERVER_READY_TIMEOUT_SEC,
|
@@ -45,6 +46,7 @@ class FunctionExecutor:
|
|
45
46
|
self._server: Optional[FunctionExecutorServer] = None
|
46
47
|
self._channel: Optional[grpc.aio.Channel] = None
|
47
48
|
self._invocation_state_client: Optional[InvocationStateClient] = None
|
49
|
+
self._health_checker: Optional[HealthChecker] = None
|
48
50
|
self._initialized = False
|
49
51
|
|
50
52
|
async def initialize(
|
@@ -78,6 +80,11 @@ class FunctionExecutor:
|
|
78
80
|
)
|
79
81
|
await self._invocation_state_client.start()
|
80
82
|
|
83
|
+
self._health_checker = HealthChecker(
|
84
|
+
stub=stub,
|
85
|
+
logger=self._logger,
|
86
|
+
)
|
87
|
+
|
81
88
|
self._initialized = True
|
82
89
|
except Exception:
|
83
90
|
await self.destroy()
|
@@ -91,10 +98,21 @@ class FunctionExecutor:
|
|
91
98
|
self._check_initialized()
|
92
99
|
return self._invocation_state_client
|
93
100
|
|
101
|
+
def health_checker(self) -> HealthChecker:
|
102
|
+
self._check_initialized()
|
103
|
+
return self._health_checker
|
104
|
+
|
94
105
|
async def destroy(self):
|
95
106
|
"""Destroys all resources owned by this FunctionExecutor.
|
96
107
|
|
97
108
|
Never raises any exceptions but logs them."""
|
109
|
+
try:
|
110
|
+
if self._health_checker is not None:
|
111
|
+
self._health_checker.stop()
|
112
|
+
self._health_checker = None
|
113
|
+
except Exception as e:
|
114
|
+
self._logger.error("failed to stop HealthChecker", exc_info=e)
|
115
|
+
|
98
116
|
try:
|
99
117
|
if self._invocation_state_client is not None:
|
100
118
|
await self._invocation_state_client.destroy()
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import asyncio
|
2
|
+
from collections.abc import Awaitable, Callable
|
3
|
+
from typing import Any, Optional
|
4
|
+
|
5
|
+
from grpc.aio import AioRpcError
|
6
|
+
|
7
|
+
from indexify.function_executor.proto.configuration import HEALTH_CHECK_TIMEOUT_SEC
|
8
|
+
from indexify.function_executor.proto.function_executor_pb2 import (
|
9
|
+
HealthCheckRequest,
|
10
|
+
HealthCheckResponse,
|
11
|
+
)
|
12
|
+
from indexify.function_executor.proto.function_executor_pb2_grpc import (
|
13
|
+
FunctionExecutorStub,
|
14
|
+
)
|
15
|
+
|
16
|
+
HEALTH_CHECK_POLL_PERIOD_SEC = 10
|
17
|
+
|
18
|
+
|
19
|
+
class HealthChecker:
|
20
|
+
def __init__(self, stub: FunctionExecutorStub, logger: Any):
|
21
|
+
self._stub: FunctionExecutorStub = stub
|
22
|
+
self._logger: Any = logger.bind(module=__name__)
|
23
|
+
self._health_check_loop_task: Optional[asyncio.Task] = None
|
24
|
+
self._health_check_failed_callback: Optional[Callable[[], Awaitable[None]]] = (
|
25
|
+
None
|
26
|
+
)
|
27
|
+
|
28
|
+
async def check(self) -> bool:
|
29
|
+
"""Runs the health check once and returns the result.
|
30
|
+
|
31
|
+
Does not raise any exceptions."""
|
32
|
+
try:
|
33
|
+
response: HealthCheckResponse = await self._stub.check_health(
|
34
|
+
HealthCheckRequest(), timeout=HEALTH_CHECK_TIMEOUT_SEC
|
35
|
+
)
|
36
|
+
return response.healthy
|
37
|
+
except AioRpcError:
|
38
|
+
return False
|
39
|
+
except Exception as e:
|
40
|
+
self._logger.warning("Got unexpected exception, ignoring", exc_info=e)
|
41
|
+
return False
|
42
|
+
|
43
|
+
def start(self, callback: Callable[[], Awaitable[None]]) -> None:
|
44
|
+
"""Starts periodic health checks.
|
45
|
+
|
46
|
+
The supplied callback is an async function called in the calling thread's
|
47
|
+
event loop when the health check fails. The callback is called only once
|
48
|
+
and then health checks are stopped.
|
49
|
+
|
50
|
+
Without a periodic health check a TCP client socket won't detect a server
|
51
|
+
socket problem (e.g. it's closed due to server crash) because there are no
|
52
|
+
TCP packets floating between them.
|
53
|
+
|
54
|
+
Does not raise any exceptions.
|
55
|
+
"""
|
56
|
+
if self._health_check_loop_task is not None:
|
57
|
+
return
|
58
|
+
|
59
|
+
self._health_check_failed_callback = callback
|
60
|
+
self._health_check_loop_task = asyncio.create_task(self._health_check_loop())
|
61
|
+
|
62
|
+
def stop(self) -> None:
|
63
|
+
"""Stops the periodic health checks.
|
64
|
+
|
65
|
+
Does not raise any exceptions."""
|
66
|
+
if self._health_check_loop_task is None:
|
67
|
+
return
|
68
|
+
|
69
|
+
self._health_check_loop_task.cancel()
|
70
|
+
self._health_check_loop_task = None
|
71
|
+
|
72
|
+
async def _health_check_loop(self) -> None:
|
73
|
+
while True:
|
74
|
+
if not await self.check():
|
75
|
+
break
|
76
|
+
await asyncio.sleep(HEALTH_CHECK_POLL_PERIOD_SEC)
|
77
|
+
|
78
|
+
asyncio.create_task(self._health_check_failed_callback())
|
79
|
+
self._health_check_loop_task = None
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/single_task_runner.py
RENAMED
@@ -1,6 +1,8 @@
|
|
1
|
+
from collections.abc import Awaitable, Callable
|
1
2
|
from typing import Any, Optional
|
2
3
|
|
3
4
|
import grpc
|
5
|
+
from grpc.aio import AioRpcError
|
4
6
|
|
5
7
|
from indexify.function_executor.proto.function_executor_pb2 import (
|
6
8
|
InitializeRequest,
|
@@ -52,6 +54,12 @@ class SingleTaskRunner:
|
|
52
54
|
if self._state.is_shutdown:
|
53
55
|
raise RuntimeError("Function Executor state is shutting down.")
|
54
56
|
|
57
|
+
# If Function Executor is not healthy then recreate it.
|
58
|
+
if self._state.function_executor is not None:
|
59
|
+
if not await self._state.function_executor.health_checker().check():
|
60
|
+
self._logger.error("Health check failed, destroying FunctionExecutor.")
|
61
|
+
await self._state.destroy_function_executor()
|
62
|
+
|
55
63
|
if self._state.function_executor is None:
|
56
64
|
try:
|
57
65
|
await self._create_function_executor()
|
@@ -110,13 +118,23 @@ class SingleTaskRunner:
|
|
110
118
|
async with _RunningTaskContextManager(
|
111
119
|
invocation_id=self._task_input.task.invocation_id,
|
112
120
|
task_id=self._task_input.task.id,
|
121
|
+
health_check_failed_callback=self._health_check_failed_callback,
|
113
122
|
function_executor_state=self._state,
|
114
123
|
):
|
124
|
+
# If this RPC failed due to customer code crashing the server we won't be
|
125
|
+
# able to detect this. We'll treat this as our own error for now and thus
|
126
|
+
# let the AioRpcError to be raised here.
|
115
127
|
response: RunTaskResponse = await FunctionExecutorStub(channel).run_task(
|
116
128
|
request
|
117
129
|
)
|
118
130
|
return _task_output(task=self._task_input.task, response=response)
|
119
131
|
|
132
|
+
async def _health_check_failed_callback(self):
|
133
|
+
# The Function Executor needs to get recreated on next task run.
|
134
|
+
self._logger.error("Health check failed, destroying FunctionExecutor.")
|
135
|
+
async with self._state.lock:
|
136
|
+
await self._state.destroy_function_executor()
|
137
|
+
|
120
138
|
|
121
139
|
class _RunningTaskContextManager:
|
122
140
|
"""Performs all the actions required before and after running a task."""
|
@@ -125,10 +143,14 @@ class _RunningTaskContextManager:
|
|
125
143
|
self,
|
126
144
|
invocation_id: str,
|
127
145
|
task_id: str,
|
146
|
+
health_check_failed_callback: Callable[[], Awaitable[None]],
|
128
147
|
function_executor_state: FunctionExecutorState,
|
129
148
|
):
|
130
149
|
self._invocation_id: str = invocation_id
|
131
150
|
self._task_id: str = task_id
|
151
|
+
self._health_check_failed_callback: Callable[[], Awaitable[None]] = (
|
152
|
+
health_check_failed_callback
|
153
|
+
)
|
132
154
|
self._state: FunctionExecutorState = function_executor_state
|
133
155
|
|
134
156
|
async def __aenter__(self):
|
@@ -137,6 +159,9 @@ class _RunningTaskContextManager:
|
|
137
159
|
task_id=self._task_id,
|
138
160
|
invocation_id=self._invocation_id,
|
139
161
|
)
|
162
|
+
self._state.function_executor.health_checker().start(
|
163
|
+
self._health_check_failed_callback
|
164
|
+
)
|
140
165
|
# Unlock the state so other tasks can act depending on it.
|
141
166
|
self._state.lock.release()
|
142
167
|
return self
|
@@ -144,9 +169,12 @@ class _RunningTaskContextManager:
|
|
144
169
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
145
170
|
await self._state.lock.acquire()
|
146
171
|
self._state.decrement_running_tasks()
|
147
|
-
|
148
|
-
|
149
|
-
|
172
|
+
# Health check callback could destroy the FunctionExecutor.
|
173
|
+
if self._state.function_executor is not None:
|
174
|
+
self._state.function_executor.invocation_state_client().remove_task_to_invocation_id_entry(
|
175
|
+
task_id=self._task_id
|
176
|
+
)
|
177
|
+
self._state.function_executor.health_checker().stop()
|
150
178
|
|
151
179
|
|
152
180
|
def _task_output(task: Task, response: RunTaskResponse) -> TaskOutput:
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor.proto
RENAMED
@@ -106,6 +106,12 @@ message RunTaskResponse {
|
|
106
106
|
optional bool success = 7;
|
107
107
|
}
|
108
108
|
|
109
|
+
message HealthCheckRequest {}
|
110
|
+
|
111
|
+
message HealthCheckResponse {
|
112
|
+
optional bool healthy = 1;
|
113
|
+
}
|
114
|
+
|
109
115
|
service FunctionExecutor {
|
110
116
|
// Initializes the Function Executor to run tasks
|
111
117
|
// for a particular function. This method is called only
|
@@ -119,4 +125,6 @@ service FunctionExecutor {
|
|
119
125
|
// Executes the task defined in the request.
|
120
126
|
// Multiple tasks can be running in parallel.
|
121
127
|
rpc run_task(RunTaskRequest) returns (RunTaskResponse);
|
128
|
+
// Health check method to check if the Function Executor is healthy.
|
129
|
+
rpc check_health(HealthCheckRequest) returns (HealthCheckResponse);
|
122
130
|
}
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2.py
RENAMED
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
|
|
24
24
|
|
25
25
|
|
26
26
|
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
|
27
|
-
b'\n8indexify/function_executor/proto/function_executor.proto\x12\x19\x66unction_executor_service"i\n\x10SerializedObject\x12\x0f\n\x05\x62ytes\x18\x01 \x01(\x0cH\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x19\n\x0c\x63ontent_type\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04\x64\x61taB\x0f\n\r_content_type"\x88\x02\n\x11InitializeRequest\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\ngraph_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rgraph_version\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rfunction_name\x18\x05 \x01(\tH\x03\x88\x01\x01\x12?\n\x05graph\x18\x07 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x04\x88\x01\x01\x42\x0c\n\n_namespaceB\r\n\x0b_graph_nameB\x10\n\x0e_graph_versionB\x10\n\x0e_function_nameB\x08\n\x06_graph"f\n\x12InitializeResponse\x12\x14\n\x07success\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x63ustomer_error\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_successB\x11\n\x0f_customer_error"\x80\x01\n\x19SetInvocationStateRequest\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12?\n\x05value\x18\x02 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x01\x88\x01\x01\x42\x06\n\x04_keyB\x08\n\x06_value"\x1c\n\x1aSetInvocationStateResponse"5\n\x19GetInvocationStateRequest\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_key"\x81\x01\n\x1aGetInvocationStateResponse\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12?\n\x05value\x18\x02 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x01\x88\x01\x01\x42\x06\n\x04_keyB\x08\n\x06_value"\xf7\x01\n\x16InvocationStateRequest\x12\x17\n\nrequest_id\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x07task_id\x18\x02 \x01(\tH\x02\x88\x01\x01\x12\x43\n\x03set\x18\x03 \x01(\x0b\x32\x34.function_executor_service.SetInvocationStateRequestH\x00\x12\x43\n\x03get\x18\x04 \x01(\x0b\x32\x34.function_executor_service.GetInvocationStateRequestH\x00\x42\t\n\x07requestB\r\n\x0b_request_idB\n\n\x08_task_id"\xfb\x01\n\x17InvocationStateResponse\x12\x17\n\nrequest_id\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x07success\x18\x02 \x01(\x08H\x02\x88\x01\x01\x12\x44\n\x03set\x18\x03 \x01(\x0b\x32\x35.function_executor_service.SetInvocationStateResponseH\x00\x12\x44\n\x03get\x18\x04 \x01(\x0b\x32\x35.function_executor_service.GetInvocationStateResponseH\x00\x42\n\n\x08responseB\r\n\x0b_request_idB\n\n\x08_success"N\n\x0e\x46unctionOutput\x12<\n\x07outputs\x18\x01 \x03(\x0b\x32+.function_executor_service.SerializedObject"\x1d\n\x0cRouterOutput\x12\r\n\x05\x65\x64ges\x18\x01 \x03(\t"\xda\x03\n\x0eRunTaskRequest\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\ngraph_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rgraph_version\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rfunction_name\x18\x04 \x01(\tH\x03\x88\x01\x01\x12 \n\x13graph_invocation_id\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07task_id\x18\x06 \x01(\tH\x05\x88\x01\x01\x12H\n\x0e\x66unction_input\x18\x07 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x06\x88\x01\x01\x12M\n\x13\x66unction_init_value\x18\x08 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x07\x88\x01\x01\x42\x0c\n\n_namespaceB\r\n\x0b_graph_nameB\x10\n\x0e_graph_versionB\x10\n\x0e_function_nameB\x16\n\x14_graph_invocation_idB\n\n\x08_task_idB\x11\n\x0f_function_inputB\x16\n\x14_function_init_value"\xf1\x02\n\x0fRunTaskResponse\x12\x14\n\x07task_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12G\n\x0f\x66unction_output\x18\x02 \x01(\x0b\x32).function_executor_service.FunctionOutputH\x01\x88\x01\x01\x12\x43\n\rrouter_output\x18\x03 \x01(\x0b\x32\'.function_executor_service.RouterOutputH\x02\x88\x01\x01\x12\x13\n\x06stdout\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06stderr\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x17\n\nis_reducer\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x14\n\x07success\x18\x07 \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_task_idB\x12\n\x10_function_outputB\x10\n\x0e_router_outputB\t\n\x07_stdoutB\t\n\x07_stderrB\r\n\x0b_is_reducerB\n\n\
|
27
|
+
b'\n8indexify/function_executor/proto/function_executor.proto\x12\x19\x66unction_executor_service"i\n\x10SerializedObject\x12\x0f\n\x05\x62ytes\x18\x01 \x01(\x0cH\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x19\n\x0c\x63ontent_type\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04\x64\x61taB\x0f\n\r_content_type"\x88\x02\n\x11InitializeRequest\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\ngraph_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rgraph_version\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rfunction_name\x18\x05 \x01(\tH\x03\x88\x01\x01\x12?\n\x05graph\x18\x07 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x04\x88\x01\x01\x42\x0c\n\n_namespaceB\r\n\x0b_graph_nameB\x10\n\x0e_graph_versionB\x10\n\x0e_function_nameB\x08\n\x06_graph"f\n\x12InitializeResponse\x12\x14\n\x07success\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x63ustomer_error\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_successB\x11\n\x0f_customer_error"\x80\x01\n\x19SetInvocationStateRequest\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12?\n\x05value\x18\x02 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x01\x88\x01\x01\x42\x06\n\x04_keyB\x08\n\x06_value"\x1c\n\x1aSetInvocationStateResponse"5\n\x19GetInvocationStateRequest\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_key"\x81\x01\n\x1aGetInvocationStateResponse\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12?\n\x05value\x18\x02 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x01\x88\x01\x01\x42\x06\n\x04_keyB\x08\n\x06_value"\xf7\x01\n\x16InvocationStateRequest\x12\x17\n\nrequest_id\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x07task_id\x18\x02 \x01(\tH\x02\x88\x01\x01\x12\x43\n\x03set\x18\x03 \x01(\x0b\x32\x34.function_executor_service.SetInvocationStateRequestH\x00\x12\x43\n\x03get\x18\x04 \x01(\x0b\x32\x34.function_executor_service.GetInvocationStateRequestH\x00\x42\t\n\x07requestB\r\n\x0b_request_idB\n\n\x08_task_id"\xfb\x01\n\x17InvocationStateResponse\x12\x17\n\nrequest_id\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x07success\x18\x02 \x01(\x08H\x02\x88\x01\x01\x12\x44\n\x03set\x18\x03 \x01(\x0b\x32\x35.function_executor_service.SetInvocationStateResponseH\x00\x12\x44\n\x03get\x18\x04 \x01(\x0b\x32\x35.function_executor_service.GetInvocationStateResponseH\x00\x42\n\n\x08responseB\r\n\x0b_request_idB\n\n\x08_success"N\n\x0e\x46unctionOutput\x12<\n\x07outputs\x18\x01 \x03(\x0b\x32+.function_executor_service.SerializedObject"\x1d\n\x0cRouterOutput\x12\r\n\x05\x65\x64ges\x18\x01 \x03(\t"\xda\x03\n\x0eRunTaskRequest\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\ngraph_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rgraph_version\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rfunction_name\x18\x04 \x01(\tH\x03\x88\x01\x01\x12 \n\x13graph_invocation_id\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07task_id\x18\x06 \x01(\tH\x05\x88\x01\x01\x12H\n\x0e\x66unction_input\x18\x07 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x06\x88\x01\x01\x12M\n\x13\x66unction_init_value\x18\x08 \x01(\x0b\x32+.function_executor_service.SerializedObjectH\x07\x88\x01\x01\x42\x0c\n\n_namespaceB\r\n\x0b_graph_nameB\x10\n\x0e_graph_versionB\x10\n\x0e_function_nameB\x16\n\x14_graph_invocation_idB\n\n\x08_task_idB\x11\n\x0f_function_inputB\x16\n\x14_function_init_value"\xf1\x02\n\x0fRunTaskResponse\x12\x14\n\x07task_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12G\n\x0f\x66unction_output\x18\x02 \x01(\x0b\x32).function_executor_service.FunctionOutputH\x01\x88\x01\x01\x12\x43\n\rrouter_output\x18\x03 \x01(\x0b\x32\'.function_executor_service.RouterOutputH\x02\x88\x01\x01\x12\x13\n\x06stdout\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06stderr\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x17\n\nis_reducer\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x14\n\x07success\x18\x07 \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_task_idB\x12\n\x10_function_outputB\x10\n\x0e_router_outputB\t\n\x07_stdoutB\t\n\x07_stderrB\r\n\x0b_is_reducerB\n\n\x08_success"\x14\n\x12HealthCheckRequest"7\n\x13HealthCheckResponse\x12\x14\n\x07healthy\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_healthy2\xe1\x03\n\x10\x46unctionExecutor\x12i\n\ninitialize\x12,.function_executor_service.InitializeRequest\x1a-.function_executor_service.InitializeResponse\x12\x8f\x01\n"initialize_invocation_state_server\x12\x32.function_executor_service.InvocationStateResponse\x1a\x31.function_executor_service.InvocationStateRequest(\x01\x30\x01\x12\x61\n\x08run_task\x12).function_executor_service.RunTaskRequest\x1a*.function_executor_service.RunTaskResponse\x12m\n\x0c\x63heck_health\x12-.function_executor_service.HealthCheckRequest\x1a..function_executor_service.HealthCheckResponseb\x06proto3'
|
28
28
|
)
|
29
29
|
|
30
30
|
_globals = globals()
|
@@ -60,6 +60,10 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
60
60
|
_globals["_RUNTASKREQUEST"]._serialized_end = 2003
|
61
61
|
_globals["_RUNTASKRESPONSE"]._serialized_start = 2006
|
62
62
|
_globals["_RUNTASKRESPONSE"]._serialized_end = 2375
|
63
|
-
_globals["
|
64
|
-
_globals["
|
63
|
+
_globals["_HEALTHCHECKREQUEST"]._serialized_start = 2377
|
64
|
+
_globals["_HEALTHCHECKREQUEST"]._serialized_end = 2397
|
65
|
+
_globals["_HEALTHCHECKRESPONSE"]._serialized_start = 2399
|
66
|
+
_globals["_HEALTHCHECKRESPONSE"]._serialized_end = 2454
|
67
|
+
_globals["_FUNCTIONEXECUTOR"]._serialized_start = 2457
|
68
|
+
_globals["_FUNCTIONEXECUTOR"]._serialized_end = 2938
|
65
69
|
# @@protoc_insertion_point(module_scope)
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2.pyi
RENAMED
@@ -213,3 +213,13 @@ class RunTaskResponse(_message.Message):
|
|
213
213
|
is_reducer: bool = ...,
|
214
214
|
success: bool = ...,
|
215
215
|
) -> None: ...
|
216
|
+
|
217
|
+
class HealthCheckRequest(_message.Message):
|
218
|
+
__slots__ = ()
|
219
|
+
def __init__(self) -> None: ...
|
220
|
+
|
221
|
+
class HealthCheckResponse(_message.Message):
|
222
|
+
__slots__ = ("healthy",)
|
223
|
+
HEALTHY_FIELD_NUMBER: _ClassVar[int]
|
224
|
+
healthy: bool
|
225
|
+
def __init__(self, healthy: bool = ...) -> None: ...
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/proto/function_executor_pb2_grpc.py
RENAMED
@@ -58,6 +58,12 @@ class FunctionExecutorStub(object):
|
|
58
58
|
response_deserializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.RunTaskResponse.FromString,
|
59
59
|
_registered_method=True,
|
60
60
|
)
|
61
|
+
self.check_health = channel.unary_unary(
|
62
|
+
"/function_executor_service.FunctionExecutor/check_health",
|
63
|
+
request_serializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckRequest.SerializeToString,
|
64
|
+
response_deserializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckResponse.FromString,
|
65
|
+
_registered_method=True,
|
66
|
+
)
|
61
67
|
|
62
68
|
|
63
69
|
class FunctionExecutorServicer(object):
|
@@ -90,6 +96,12 @@ class FunctionExecutorServicer(object):
|
|
90
96
|
context.set_details("Method not implemented!")
|
91
97
|
raise NotImplementedError("Method not implemented!")
|
92
98
|
|
99
|
+
def check_health(self, request, context):
|
100
|
+
"""Health check method to check if the Function Executor is healthy."""
|
101
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
102
|
+
context.set_details("Method not implemented!")
|
103
|
+
raise NotImplementedError("Method not implemented!")
|
104
|
+
|
93
105
|
|
94
106
|
def add_FunctionExecutorServicer_to_server(servicer, server):
|
95
107
|
rpc_method_handlers = {
|
@@ -108,6 +120,11 @@ def add_FunctionExecutorServicer_to_server(servicer, server):
|
|
108
120
|
request_deserializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.RunTaskRequest.FromString,
|
109
121
|
response_serializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.RunTaskResponse.SerializeToString,
|
110
122
|
),
|
123
|
+
"check_health": grpc.unary_unary_rpc_method_handler(
|
124
|
+
servicer.check_health,
|
125
|
+
request_deserializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckRequest.FromString,
|
126
|
+
response_serializer=indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckResponse.SerializeToString,
|
127
|
+
),
|
111
128
|
}
|
112
129
|
generic_handler = grpc.method_handlers_generic_handler(
|
113
130
|
"function_executor_service.FunctionExecutor", rpc_method_handlers
|
@@ -211,3 +228,33 @@ class FunctionExecutor(object):
|
|
211
228
|
metadata,
|
212
229
|
_registered_method=True,
|
213
230
|
)
|
231
|
+
|
232
|
+
@staticmethod
|
233
|
+
def check_health(
|
234
|
+
request,
|
235
|
+
target,
|
236
|
+
options=(),
|
237
|
+
channel_credentials=None,
|
238
|
+
call_credentials=None,
|
239
|
+
insecure=False,
|
240
|
+
compression=None,
|
241
|
+
wait_for_ready=None,
|
242
|
+
timeout=None,
|
243
|
+
metadata=None,
|
244
|
+
):
|
245
|
+
return grpc.experimental.unary_unary(
|
246
|
+
request,
|
247
|
+
target,
|
248
|
+
"/function_executor_service.FunctionExecutor/check_health",
|
249
|
+
indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckRequest.SerializeToString,
|
250
|
+
indexify_dot_function__executor_dot_proto_dot_function__executor__pb2.HealthCheckResponse.FromString,
|
251
|
+
options,
|
252
|
+
channel_credentials,
|
253
|
+
insecure,
|
254
|
+
call_credentials,
|
255
|
+
compression,
|
256
|
+
wait_for_ready,
|
257
|
+
timeout,
|
258
|
+
metadata,
|
259
|
+
_registered_method=True,
|
260
|
+
)
|
@@ -13,6 +13,8 @@ from .initialize_request_validator import InitializeRequestValidator
|
|
13
13
|
from .invocation_state.invocation_state_proxy_server import InvocationStateProxyServer
|
14
14
|
from .invocation_state.proxied_invocation_state import ProxiedInvocationState
|
15
15
|
from .proto.function_executor_pb2 import (
|
16
|
+
HealthCheckRequest,
|
17
|
+
HealthCheckResponse,
|
16
18
|
InitializeRequest,
|
17
19
|
InitializeResponse,
|
18
20
|
InvocationStateResponse,
|
@@ -120,3 +122,12 @@ class Service(FunctionExecutorServicer):
|
|
120
122
|
raise ValueError(
|
121
123
|
f"This Function Executor is not initialized for this function_name {request.function_name}"
|
122
124
|
)
|
125
|
+
|
126
|
+
def check_health(
|
127
|
+
self, request: HealthCheckRequest, context: grpc.ServicerContext
|
128
|
+
) -> HealthCheckResponse:
|
129
|
+
# This health check validates that the Server:
|
130
|
+
# - Has its process alive (not exited).
|
131
|
+
# - Didn't exhaust its thread pool.
|
132
|
+
# - Is able to communicate over its server socket.
|
133
|
+
return HealthCheckResponse(healthy=True)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/function_executor_state.py
RENAMED
File without changes
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/executor/function_executor/invocation_state_client.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/handlers/run_function/handler.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{indexify-0.3.3 → indexify-0.3.4}/src/indexify/function_executor/initialize_request_validator.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|