opengris-scaler 1.12.7__cp38-cp38-musllinux_1_2_x86_64.whl
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.
Potentially problematic release.
This version of opengris-scaler might be problematic. Click here for more details.
- opengris_scaler-1.12.7.dist-info/METADATA +729 -0
- opengris_scaler-1.12.7.dist-info/RECORD +234 -0
- opengris_scaler-1.12.7.dist-info/WHEEL +5 -0
- opengris_scaler-1.12.7.dist-info/entry_points.txt +9 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE +201 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE.spdx +7 -0
- opengris_scaler-1.12.7.dist-info/licenses/NOTICE +8 -0
- opengris_scaler.libs/libcapnp-1-61c06778.1.0.so +0 -0
- opengris_scaler.libs/libgcc_s-2298274a.so.1 +0 -0
- opengris_scaler.libs/libkj-1-21b63b70.1.0.so +0 -0
- opengris_scaler.libs/libstdc++-08d5c7eb.so.6.0.33 +0 -0
- scaler/CMakeLists.txt +11 -0
- scaler/__init__.py +14 -0
- scaler/about.py +5 -0
- scaler/client/__init__.py +0 -0
- scaler/client/agent/__init__.py +0 -0
- scaler/client/agent/client_agent.py +210 -0
- scaler/client/agent/disconnect_manager.py +27 -0
- scaler/client/agent/future_manager.py +112 -0
- scaler/client/agent/heartbeat_manager.py +74 -0
- scaler/client/agent/mixins.py +89 -0
- scaler/client/agent/object_manager.py +98 -0
- scaler/client/agent/task_manager.py +64 -0
- scaler/client/client.py +635 -0
- scaler/client/future.py +252 -0
- scaler/client/object_buffer.py +129 -0
- scaler/client/object_reference.py +25 -0
- scaler/client/serializer/__init__.py +0 -0
- scaler/client/serializer/default.py +16 -0
- scaler/client/serializer/mixins.py +38 -0
- scaler/cluster/__init__.py +0 -0
- scaler/cluster/cluster.py +115 -0
- scaler/cluster/combo.py +148 -0
- scaler/cluster/object_storage_server.py +45 -0
- scaler/cluster/scheduler.py +83 -0
- scaler/config/__init__.py +0 -0
- scaler/config/defaults.py +87 -0
- scaler/config/loader.py +95 -0
- scaler/config/mixins.py +15 -0
- scaler/config/section/__init__.py +0 -0
- scaler/config/section/cluster.py +56 -0
- scaler/config/section/native_worker_adapter.py +44 -0
- scaler/config/section/object_storage_server.py +7 -0
- scaler/config/section/scheduler.py +53 -0
- scaler/config/section/symphony_worker_adapter.py +47 -0
- scaler/config/section/top.py +13 -0
- scaler/config/section/webui.py +16 -0
- scaler/config/types/__init__.py +0 -0
- scaler/config/types/object_storage_server.py +45 -0
- scaler/config/types/worker.py +57 -0
- scaler/config/types/zmq.py +79 -0
- scaler/entry_points/__init__.py +0 -0
- scaler/entry_points/cluster.py +133 -0
- scaler/entry_points/object_storage_server.py +41 -0
- scaler/entry_points/scheduler.py +135 -0
- scaler/entry_points/top.py +286 -0
- scaler/entry_points/webui.py +26 -0
- scaler/entry_points/worker_adapter_native.py +137 -0
- scaler/entry_points/worker_adapter_symphony.py +102 -0
- scaler/io/__init__.py +0 -0
- scaler/io/async_binder.py +85 -0
- scaler/io/async_connector.py +95 -0
- scaler/io/async_object_storage_connector.py +185 -0
- scaler/io/mixins.py +154 -0
- scaler/io/sync_connector.py +68 -0
- scaler/io/sync_object_storage_connector.py +185 -0
- scaler/io/sync_subscriber.py +83 -0
- scaler/io/utility.py +31 -0
- scaler/io/ymq/CMakeLists.txt +98 -0
- scaler/io/ymq/__init__.py +0 -0
- scaler/io/ymq/_ymq.pyi +96 -0
- scaler/io/ymq/_ymq.so +0 -0
- scaler/io/ymq/bytes.h +114 -0
- scaler/io/ymq/common.h +29 -0
- scaler/io/ymq/configuration.h +60 -0
- scaler/io/ymq/epoll_context.cpp +185 -0
- scaler/io/ymq/epoll_context.h +85 -0
- scaler/io/ymq/error.h +132 -0
- scaler/io/ymq/event_loop.h +55 -0
- scaler/io/ymq/event_loop_thread.cpp +64 -0
- scaler/io/ymq/event_loop_thread.h +46 -0
- scaler/io/ymq/event_manager.h +81 -0
- scaler/io/ymq/file_descriptor.h +203 -0
- scaler/io/ymq/interruptive_concurrent_queue.h +169 -0
- scaler/io/ymq/io_context.cpp +98 -0
- scaler/io/ymq/io_context.h +44 -0
- scaler/io/ymq/io_socket.cpp +299 -0
- scaler/io/ymq/io_socket.h +121 -0
- scaler/io/ymq/iocp_context.cpp +102 -0
- scaler/io/ymq/iocp_context.h +83 -0
- scaler/io/ymq/logging.h +163 -0
- scaler/io/ymq/message.h +15 -0
- scaler/io/ymq/message_connection.h +16 -0
- scaler/io/ymq/message_connection_tcp.cpp +672 -0
- scaler/io/ymq/message_connection_tcp.h +96 -0
- scaler/io/ymq/network_utils.h +179 -0
- scaler/io/ymq/pymod_ymq/bytes.h +113 -0
- scaler/io/ymq/pymod_ymq/exception.h +124 -0
- scaler/io/ymq/pymod_ymq/gil.h +15 -0
- scaler/io/ymq/pymod_ymq/io_context.h +166 -0
- scaler/io/ymq/pymod_ymq/io_socket.h +285 -0
- scaler/io/ymq/pymod_ymq/message.h +99 -0
- scaler/io/ymq/pymod_ymq/python.h +153 -0
- scaler/io/ymq/pymod_ymq/ymq.cpp +23 -0
- scaler/io/ymq/pymod_ymq/ymq.h +357 -0
- scaler/io/ymq/readme.md +114 -0
- scaler/io/ymq/simple_interface.cpp +80 -0
- scaler/io/ymq/simple_interface.h +24 -0
- scaler/io/ymq/tcp_client.cpp +367 -0
- scaler/io/ymq/tcp_client.h +75 -0
- scaler/io/ymq/tcp_operations.h +41 -0
- scaler/io/ymq/tcp_server.cpp +410 -0
- scaler/io/ymq/tcp_server.h +79 -0
- scaler/io/ymq/third_party/concurrentqueue.h +3747 -0
- scaler/io/ymq/timed_queue.h +272 -0
- scaler/io/ymq/timestamp.h +102 -0
- scaler/io/ymq/typedefs.h +20 -0
- scaler/io/ymq/utils.h +34 -0
- scaler/io/ymq/ymq.py +130 -0
- scaler/object_storage/CMakeLists.txt +50 -0
- scaler/object_storage/__init__.py +0 -0
- scaler/object_storage/constants.h +11 -0
- scaler/object_storage/defs.h +14 -0
- scaler/object_storage/io_helper.cpp +44 -0
- scaler/object_storage/io_helper.h +9 -0
- scaler/object_storage/message.cpp +56 -0
- scaler/object_storage/message.h +130 -0
- scaler/object_storage/object_manager.cpp +126 -0
- scaler/object_storage/object_manager.h +52 -0
- scaler/object_storage/object_storage_server.cpp +359 -0
- scaler/object_storage/object_storage_server.h +126 -0
- scaler/object_storage/object_storage_server.so +0 -0
- scaler/object_storage/pymod_object_storage_server.cpp +104 -0
- scaler/protocol/__init__.py +0 -0
- scaler/protocol/capnp/__init__.py +0 -0
- scaler/protocol/capnp/_python.py +6 -0
- scaler/protocol/capnp/common.capnp +63 -0
- scaler/protocol/capnp/message.capnp +216 -0
- scaler/protocol/capnp/object_storage.capnp +52 -0
- scaler/protocol/capnp/status.capnp +73 -0
- scaler/protocol/introduction.md +105 -0
- scaler/protocol/python/__init__.py +0 -0
- scaler/protocol/python/common.py +135 -0
- scaler/protocol/python/message.py +726 -0
- scaler/protocol/python/mixins.py +13 -0
- scaler/protocol/python/object_storage.py +118 -0
- scaler/protocol/python/status.py +279 -0
- scaler/protocol/worker.md +228 -0
- scaler/scheduler/__init__.py +0 -0
- scaler/scheduler/allocate_policy/__init__.py +0 -0
- scaler/scheduler/allocate_policy/allocate_policy.py +9 -0
- scaler/scheduler/allocate_policy/capability_allocate_policy.py +280 -0
- scaler/scheduler/allocate_policy/even_load_allocate_policy.py +159 -0
- scaler/scheduler/allocate_policy/mixins.py +55 -0
- scaler/scheduler/controllers/__init__.py +0 -0
- scaler/scheduler/controllers/balance_controller.py +65 -0
- scaler/scheduler/controllers/client_controller.py +131 -0
- scaler/scheduler/controllers/config_controller.py +31 -0
- scaler/scheduler/controllers/graph_controller.py +424 -0
- scaler/scheduler/controllers/information_controller.py +81 -0
- scaler/scheduler/controllers/mixins.py +201 -0
- scaler/scheduler/controllers/object_controller.py +147 -0
- scaler/scheduler/controllers/scaling_controller.py +86 -0
- scaler/scheduler/controllers/task_controller.py +373 -0
- scaler/scheduler/controllers/worker_controller.py +168 -0
- scaler/scheduler/object_usage/__init__.py +0 -0
- scaler/scheduler/object_usage/object_tracker.py +131 -0
- scaler/scheduler/scheduler.py +253 -0
- scaler/scheduler/task/__init__.py +0 -0
- scaler/scheduler/task/task_state_machine.py +92 -0
- scaler/scheduler/task/task_state_manager.py +61 -0
- scaler/ui/__init__.py +0 -0
- scaler/ui/constants.py +9 -0
- scaler/ui/live_display.py +118 -0
- scaler/ui/memory_window.py +146 -0
- scaler/ui/setting_page.py +47 -0
- scaler/ui/task_graph.py +370 -0
- scaler/ui/task_log.py +83 -0
- scaler/ui/utility.py +35 -0
- scaler/ui/webui.py +125 -0
- scaler/ui/worker_processors.py +85 -0
- scaler/utility/__init__.py +0 -0
- scaler/utility/debug.py +19 -0
- scaler/utility/event_list.py +63 -0
- scaler/utility/event_loop.py +58 -0
- scaler/utility/exceptions.py +42 -0
- scaler/utility/formatter.py +44 -0
- scaler/utility/graph/__init__.py +0 -0
- scaler/utility/graph/optimization.py +27 -0
- scaler/utility/graph/topological_sorter.py +11 -0
- scaler/utility/graph/topological_sorter_graphblas.py +174 -0
- scaler/utility/identifiers.py +105 -0
- scaler/utility/logging/__init__.py +0 -0
- scaler/utility/logging/decorators.py +25 -0
- scaler/utility/logging/scoped_logger.py +33 -0
- scaler/utility/logging/utility.py +183 -0
- scaler/utility/many_to_many_dict.py +123 -0
- scaler/utility/metadata/__init__.py +0 -0
- scaler/utility/metadata/profile_result.py +31 -0
- scaler/utility/metadata/task_flags.py +30 -0
- scaler/utility/mixins.py +13 -0
- scaler/utility/network_util.py +7 -0
- scaler/utility/one_to_many_dict.py +72 -0
- scaler/utility/queues/__init__.py +0 -0
- scaler/utility/queues/async_indexed_queue.py +37 -0
- scaler/utility/queues/async_priority_queue.py +70 -0
- scaler/utility/queues/async_sorted_priority_queue.py +45 -0
- scaler/utility/queues/indexed_queue.py +114 -0
- scaler/utility/serialization.py +9 -0
- scaler/version.txt +1 -0
- scaler/worker/__init__.py +0 -0
- scaler/worker/agent/__init__.py +0 -0
- scaler/worker/agent/heartbeat_manager.py +107 -0
- scaler/worker/agent/mixins.py +137 -0
- scaler/worker/agent/processor/__init__.py +0 -0
- scaler/worker/agent/processor/object_cache.py +107 -0
- scaler/worker/agent/processor/processor.py +279 -0
- scaler/worker/agent/processor/streaming_buffer.py +28 -0
- scaler/worker/agent/processor_holder.py +145 -0
- scaler/worker/agent/processor_manager.py +365 -0
- scaler/worker/agent/profiling_manager.py +109 -0
- scaler/worker/agent/task_manager.py +150 -0
- scaler/worker/agent/timeout_manager.py +19 -0
- scaler/worker/preload.py +84 -0
- scaler/worker/worker.py +264 -0
- scaler/worker_adapter/__init__.py +0 -0
- scaler/worker_adapter/native.py +154 -0
- scaler/worker_adapter/symphony/__init__.py +0 -0
- scaler/worker_adapter/symphony/callback.py +45 -0
- scaler/worker_adapter/symphony/heartbeat_manager.py +79 -0
- scaler/worker_adapter/symphony/message.py +24 -0
- scaler/worker_adapter/symphony/task_manager.py +288 -0
- scaler/worker_adapter/symphony/worker.py +205 -0
- scaler/worker_adapter/symphony/worker_adapter.py +142 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#include "scaler/object_storage/object_storage_server.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
#include <exception>
|
|
5
|
+
#include <future>
|
|
6
|
+
|
|
7
|
+
#include "scaler/io/ymq/configuration.h"
|
|
8
|
+
#include "scaler/io/ymq/error.h"
|
|
9
|
+
#include "scaler/io/ymq/simple_interface.h"
|
|
10
|
+
#include "scaler/io/ymq/typedefs.h"
|
|
11
|
+
#include "scaler/object_storage/message.h"
|
|
12
|
+
|
|
13
|
+
namespace scaler {
|
|
14
|
+
namespace object_storage {
|
|
15
|
+
|
|
16
|
+
ObjectStorageServer::ObjectStorageServer()
|
|
17
|
+
{
|
|
18
|
+
initServerReadyFds();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
ObjectStorageServer::~ObjectStorageServer()
|
|
22
|
+
{
|
|
23
|
+
closeServerReadyFds();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void ObjectStorageServer::run(
|
|
27
|
+
std::string name,
|
|
28
|
+
std::string port,
|
|
29
|
+
ObjectStorageServer::Identity identity,
|
|
30
|
+
std::string log_level,
|
|
31
|
+
std::string log_format,
|
|
32
|
+
std::vector<std::string> log_paths)
|
|
33
|
+
{
|
|
34
|
+
_logger = scaler::ymq::Logger(log_format, std::move(log_paths), scaler::ymq::Logger::stringToLogLevel(log_level));
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
// NOTE: Setup IOSocket synchronously here because it is a one-time thing.
|
|
38
|
+
const auto socketType {ymq::IOSocketType::Binder};
|
|
39
|
+
_ioSocket = ymq::syncCreateSocket(_ioContext, socketType, std::move(identity));
|
|
40
|
+
const std::string networkAddress {"tcp://" + name + ':' + port};
|
|
41
|
+
ymq::syncBindSocket(_ioSocket, std::move(networkAddress));
|
|
42
|
+
|
|
43
|
+
setServerReadyFd();
|
|
44
|
+
|
|
45
|
+
_logger.log(scaler::ymq::Logger::LoggingLevel::info, "ObjectStorageServer: started");
|
|
46
|
+
|
|
47
|
+
processRequests();
|
|
48
|
+
|
|
49
|
+
_ioContext.removeIOSocket(_ioSocket);
|
|
50
|
+
} catch (const std::exception& e) {
|
|
51
|
+
_logger.log(
|
|
52
|
+
scaler::ymq::Logger::LoggingLevel::error,
|
|
53
|
+
"ObjectStorageServer: unexpected server error, reason: ",
|
|
54
|
+
e.what());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void ObjectStorageServer::waitUntilReady()
|
|
59
|
+
{
|
|
60
|
+
uint64_t value;
|
|
61
|
+
ssize_t ret = read(onServerReadyReader, &value, sizeof(uint64_t));
|
|
62
|
+
|
|
63
|
+
if (ret != sizeof(uint64_t)) {
|
|
64
|
+
_logger.log(
|
|
65
|
+
scaler::ymq::Logger::LoggingLevel::error,
|
|
66
|
+
"ObjectStorageServer: read from onServerReadyReader failed, errno=",
|
|
67
|
+
errno);
|
|
68
|
+
std::terminate();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void ObjectStorageServer::shutdown()
|
|
73
|
+
{
|
|
74
|
+
_ioContext.requestIOSocketStop(_ioSocket);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void ObjectStorageServer::initServerReadyFds()
|
|
78
|
+
{
|
|
79
|
+
int pipeFds[2] {};
|
|
80
|
+
int ret = pipe(pipeFds);
|
|
81
|
+
|
|
82
|
+
if (ret != 0) {
|
|
83
|
+
_logger.log(
|
|
84
|
+
scaler::ymq::Logger::LoggingLevel::error,
|
|
85
|
+
"ObjectStorageServer: create on server ready FDs failed, errno=",
|
|
86
|
+
errno);
|
|
87
|
+
std::terminate();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
onServerReadyReader = pipeFds[0];
|
|
91
|
+
onServerReadyWriter = pipeFds[1];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void ObjectStorageServer::setServerReadyFd()
|
|
95
|
+
{
|
|
96
|
+
uint64_t value = 1;
|
|
97
|
+
ssize_t ret = write(onServerReadyWriter, &value, sizeof(uint64_t));
|
|
98
|
+
|
|
99
|
+
if (ret != sizeof(uint64_t)) {
|
|
100
|
+
_logger.log(
|
|
101
|
+
scaler::ymq::Logger::LoggingLevel::error,
|
|
102
|
+
"ObjectStorageServer: write to onServerReadyWriter failed, errno=",
|
|
103
|
+
errno);
|
|
104
|
+
std::terminate();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void ObjectStorageServer::closeServerReadyFds()
|
|
109
|
+
{
|
|
110
|
+
const std::array<int, 2> fds {onServerReadyReader, onServerReadyWriter};
|
|
111
|
+
|
|
112
|
+
for (const int fd: fds) {
|
|
113
|
+
if (close(fd) != 0) {
|
|
114
|
+
_logger.log(scaler::ymq::Logger::LoggingLevel::error, "ObjectStorageServer: close failed, errno=", errno);
|
|
115
|
+
std::terminate();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
void ObjectStorageServer::processRequests()
|
|
121
|
+
{
|
|
122
|
+
using namespace std::chrono_literals;
|
|
123
|
+
Identity lastMessageIdentity;
|
|
124
|
+
std::map<Identity, std::pair<ObjectRequestHeader, Bytes>> identityToFullRequest;
|
|
125
|
+
while (true) {
|
|
126
|
+
try {
|
|
127
|
+
auto invalids = std::ranges::remove_if(_pendingSendMessageFuts, [](const auto& x) { return !x.valid(); });
|
|
128
|
+
_pendingSendMessageFuts.erase(invalids.begin(), invalids.end());
|
|
129
|
+
|
|
130
|
+
std::ranges::for_each(_pendingSendMessageFuts, [](auto& fut) {
|
|
131
|
+
if (fut.wait_for(0s) == std::future_status::ready) {
|
|
132
|
+
auto error = fut.get();
|
|
133
|
+
assert(!error);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
auto maybeMessage = ymq::syncRecvMessage(_ioSocket);
|
|
138
|
+
|
|
139
|
+
if (!maybeMessage) {
|
|
140
|
+
auto error = maybeMessage.error();
|
|
141
|
+
if (error._errorCode == ymq::Error::ErrorCode::IOSocketStopRequested) {
|
|
142
|
+
auto n = std::ranges::count_if(_pendingSendMessageFuts, [](auto& x) {
|
|
143
|
+
return x.valid() && x.wait_for(0s) == std::future_status::timeout;
|
|
144
|
+
});
|
|
145
|
+
if (!n) {
|
|
146
|
+
_logger.log(
|
|
147
|
+
scaler::ymq::Logger::LoggingLevel::info,
|
|
148
|
+
"ObjectStorageServer: stopped, number of messages leftover in the system = ",
|
|
149
|
+
std::ranges::count_if(_pendingSendMessageFuts, [](auto& x) {
|
|
150
|
+
return x.valid() && x.wait_for(0s) == std::future_status::timeout;
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (pendingRequests.size()) {
|
|
155
|
+
_logger.log(
|
|
156
|
+
scaler::ymq::Logger::LoggingLevel::info,
|
|
157
|
+
"ObjectStorageServer: stopped, number of pending requests leftover in the system = ",
|
|
158
|
+
pendingRequests.size());
|
|
159
|
+
pendingRequests.clear();
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
} else {
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const auto identity = *maybeMessage->address.as_string();
|
|
168
|
+
lastMessageIdentity = identity;
|
|
169
|
+
const auto headerOrPayload = std::move(maybeMessage->payload);
|
|
170
|
+
|
|
171
|
+
auto it = identityToFullRequest.find(identity);
|
|
172
|
+
if (it == identityToFullRequest.end()) {
|
|
173
|
+
identityToFullRequest[identity].first = ObjectRequestHeader::fromBuffer(headerOrPayload);
|
|
174
|
+
const auto& requestType = identityToFullRequest[identity].first.requestType;
|
|
175
|
+
if (requestType == ObjectRequestType::DUPLICATE_OBJECT_I_D ||
|
|
176
|
+
requestType == ObjectRequestType::SET_OBJECT) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
assert(it->second.first.payloadLength == headerOrPayload.len());
|
|
181
|
+
(it->second).second = std::move(headerOrPayload);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// NOTE: PostCondition of the previous statement: We have a full request here
|
|
185
|
+
|
|
186
|
+
auto request = std::move(identityToFullRequest[identity]);
|
|
187
|
+
identityToFullRequest.erase(identity);
|
|
188
|
+
auto client = std::make_shared<Client>(_ioSocket, identity);
|
|
189
|
+
|
|
190
|
+
switch (request.first.requestType) {
|
|
191
|
+
case ObjectRequestType::SET_OBJECT: {
|
|
192
|
+
processSetRequest(std::move(client), std::move(request));
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case ObjectRequestType::GET_OBJECT: {
|
|
196
|
+
processGetRequest(std::move(client), request.first);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case ObjectRequestType::DELETE_OBJECT: {
|
|
200
|
+
processDeleteRequest(client, request.first);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case ObjectRequestType::DUPLICATE_OBJECT_I_D: {
|
|
204
|
+
processDuplicateRequest(client, request);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
} catch (const kj::Exception& e) {
|
|
209
|
+
_ioSocket->closeConnection(std::move(lastMessageIdentity));
|
|
210
|
+
_logger.log(
|
|
211
|
+
scaler::ymq::Logger::LoggingLevel::error,
|
|
212
|
+
"ObjectStorageServer: Malformed capnp message. Connection closed, details: ",
|
|
213
|
+
e.getDescription().cStr());
|
|
214
|
+
} catch (const std::exception& e) {
|
|
215
|
+
_logger.log(
|
|
216
|
+
scaler::ymq::Logger::LoggingLevel::error, "ObjectStorageServer: unexpected error, reason: ", e.what());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
void ObjectStorageServer::processSetRequest(
|
|
222
|
+
std::shared_ptr<Client> client, std::pair<ObjectRequestHeader, Bytes> request)
|
|
223
|
+
{
|
|
224
|
+
const auto requestHeader = std::move(request.first);
|
|
225
|
+
auto requestPayload = std::move(request.second);
|
|
226
|
+
if (requestHeader.payloadLength > MEMORY_LIMIT_IN_BYTES) {
|
|
227
|
+
throw std::runtime_error(
|
|
228
|
+
"payload length is larger than MEMORY_LIMIT_IN_BYTES=" + std::to_string(MEMORY_LIMIT_IN_BYTES));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (requestHeader.payloadLength > std::numeric_limits<size_t>::max()) {
|
|
232
|
+
throw std::runtime_error("payload length is larger than SIZE_MAX=" + std::to_string(SIZE_MAX));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
auto objectPtr = objectManager.setObject(requestHeader.objectID, std::move(requestPayload));
|
|
236
|
+
|
|
237
|
+
optionallySendPendingRequests(requestHeader.objectID, objectPtr);
|
|
238
|
+
|
|
239
|
+
ObjectResponseHeader responseHeader {
|
|
240
|
+
.objectID = requestHeader.objectID,
|
|
241
|
+
.payloadLength = 0,
|
|
242
|
+
.responseID = requestHeader.requestID,
|
|
243
|
+
.responseType = ObjectResponseType::SET_O_K,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
writeMessage(client, responseHeader, {});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void ObjectStorageServer::processGetRequest(std::shared_ptr<Client> client, const ObjectRequestHeader& requestHeader)
|
|
250
|
+
{
|
|
251
|
+
auto objectPtr = objectManager.getObject(requestHeader.objectID);
|
|
252
|
+
|
|
253
|
+
if (objectPtr != nullptr) {
|
|
254
|
+
sendGetResponse(client, requestHeader, objectPtr);
|
|
255
|
+
return;
|
|
256
|
+
} else {
|
|
257
|
+
// We don't have the object yet. Send the response later after once we receive the SET request.
|
|
258
|
+
pendingRequests[requestHeader.objectID].emplace_back(client, requestHeader);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
void ObjectStorageServer::processDeleteRequest(std::shared_ptr<Client> client, ObjectRequestHeader& requestHeader)
|
|
263
|
+
{
|
|
264
|
+
bool success = objectManager.deleteObject(requestHeader.objectID);
|
|
265
|
+
|
|
266
|
+
ObjectResponseHeader responseHeader {
|
|
267
|
+
.objectID = requestHeader.objectID,
|
|
268
|
+
.payloadLength = 0,
|
|
269
|
+
.responseID = requestHeader.requestID,
|
|
270
|
+
.responseType = success ? ObjectResponseType::DEL_O_K : ObjectResponseType::DEL_NOT_EXISTS,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
writeMessage(client, responseHeader, {});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
void ObjectStorageServer::processDuplicateRequest(
|
|
277
|
+
std::shared_ptr<Client> client, std::pair<ObjectRequestHeader, Bytes> request)
|
|
278
|
+
{
|
|
279
|
+
auto requestHeader = std::move(request.first);
|
|
280
|
+
auto payload = std::move(request.second);
|
|
281
|
+
if (requestHeader.payloadLength != ObjectID::bufferSize()) {
|
|
282
|
+
throw std::runtime_error(
|
|
283
|
+
"payload length should be size_of(ObjectID)=" + std::to_string(ObjectID::bufferSize()));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
ObjectID originalObjectID = ObjectID::fromBuffer(payload);
|
|
287
|
+
|
|
288
|
+
auto objectPtr = objectManager.duplicateObject(originalObjectID, requestHeader.objectID);
|
|
289
|
+
|
|
290
|
+
std::vector<ObjectStorageServer::SendMessageFuture> res;
|
|
291
|
+
if (objectPtr != nullptr) {
|
|
292
|
+
optionallySendPendingRequests(requestHeader.objectID, objectPtr);
|
|
293
|
+
sendDuplicateResponse(client, requestHeader);
|
|
294
|
+
} else {
|
|
295
|
+
// We don't have the referenced original object yet. Send the response later once we receive the SET
|
|
296
|
+
pendingRequests[originalObjectID].emplace_back(client, requestHeader);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
void ObjectStorageServer::sendGetResponse(
|
|
301
|
+
std::shared_ptr<Client> client,
|
|
302
|
+
const ObjectRequestHeader& requestHeader,
|
|
303
|
+
std::shared_ptr<const ObjectPayload> objectPtr)
|
|
304
|
+
{
|
|
305
|
+
uint64_t payloadLength = std::min(static_cast<uint64_t>(objectPtr->size()), requestHeader.payloadLength);
|
|
306
|
+
|
|
307
|
+
ObjectResponseHeader responseHeader {
|
|
308
|
+
.objectID = requestHeader.objectID,
|
|
309
|
+
.payloadLength = payloadLength,
|
|
310
|
+
.responseID = requestHeader.requestID,
|
|
311
|
+
.responseType = ObjectResponseType::GET_O_K,
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
writeMessage(client, responseHeader, {objectPtr->data(), payloadLength});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
void ObjectStorageServer::sendDuplicateResponse(
|
|
318
|
+
std::shared_ptr<Client> client, const ObjectRequestHeader& requestHeader)
|
|
319
|
+
{
|
|
320
|
+
ObjectResponseHeader responseHeader {
|
|
321
|
+
.objectID = requestHeader.objectID,
|
|
322
|
+
.payloadLength = 0,
|
|
323
|
+
.responseID = requestHeader.requestID,
|
|
324
|
+
.responseType = ObjectResponseType::DUPLICATE_O_K,
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
writeMessage(client, responseHeader, {});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
void ObjectStorageServer::optionallySendPendingRequests(
|
|
331
|
+
const ObjectID& objectID, std::shared_ptr<const ObjectPayload> objectPtr)
|
|
332
|
+
{
|
|
333
|
+
auto it = pendingRequests.find(objectID);
|
|
334
|
+
if (it == pendingRequests.end()) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Immediately remove the object's pending requests, or else another coroutine might process them too.
|
|
339
|
+
auto requests = std::move(it->second);
|
|
340
|
+
pendingRequests.erase(it);
|
|
341
|
+
|
|
342
|
+
std::vector<ObjectStorageServer::SendMessageFuture> res;
|
|
343
|
+
for (auto& request: requests) {
|
|
344
|
+
if (request.requestHeader.requestType == ObjectRequestType::GET_OBJECT) {
|
|
345
|
+
sendGetResponse(request.client, request.requestHeader, objectPtr);
|
|
346
|
+
} else {
|
|
347
|
+
assert(request.requestHeader.requestType == ObjectRequestType::DUPLICATE_OBJECT_I_D);
|
|
348
|
+
objectManager.duplicateObject(objectID, request.requestHeader.objectID);
|
|
349
|
+
sendDuplicateResponse(request.client, request.requestHeader);
|
|
350
|
+
|
|
351
|
+
// Some other pending requests might be themselves dependent on this duplicated object.
|
|
352
|
+
optionallySendPendingRequests(request.requestHeader.objectID, objectPtr);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
}; // namespace object_storage
|
|
359
|
+
}; // namespace scaler
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <expected>
|
|
4
|
+
#include <iostream>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <span>
|
|
8
|
+
|
|
9
|
+
#include "scaler/io/ymq/configuration.h"
|
|
10
|
+
#include "scaler/io/ymq/io_context.h"
|
|
11
|
+
#include "scaler/io/ymq/io_socket.h"
|
|
12
|
+
#include "scaler/io/ymq/logging.h"
|
|
13
|
+
#include "scaler/io/ymq/simple_interface.h"
|
|
14
|
+
#include "scaler/object_storage/constants.h"
|
|
15
|
+
#include "scaler/object_storage/defs.h"
|
|
16
|
+
#include "scaler/object_storage/io_helper.h"
|
|
17
|
+
#include "scaler/object_storage/message.h"
|
|
18
|
+
#include "scaler/object_storage/object_manager.h"
|
|
19
|
+
|
|
20
|
+
namespace scaler {
|
|
21
|
+
namespace object_storage {
|
|
22
|
+
|
|
23
|
+
class ObjectStorageServer {
|
|
24
|
+
public:
|
|
25
|
+
using Identity = ymq::Configuration::IOSocketIdentity;
|
|
26
|
+
using SendMessageFuture = std::future<std::optional<ymq::Error>>;
|
|
27
|
+
|
|
28
|
+
ObjectStorageServer();
|
|
29
|
+
|
|
30
|
+
~ObjectStorageServer();
|
|
31
|
+
|
|
32
|
+
void run(
|
|
33
|
+
std::string name,
|
|
34
|
+
std::string port,
|
|
35
|
+
Identity identity = "ObjectStorageServer",
|
|
36
|
+
std::string log_level = "INFO",
|
|
37
|
+
std::string log_format = "%(levelname)s: %(message)s",
|
|
38
|
+
std::vector<std::string> log_paths = {"/dev/stdout"});
|
|
39
|
+
|
|
40
|
+
void waitUntilReady();
|
|
41
|
+
|
|
42
|
+
void shutdown();
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
struct Client {
|
|
46
|
+
std::shared_ptr<ymq::IOSocket> _ioSocket;
|
|
47
|
+
Identity _identity;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
struct PendingRequest {
|
|
51
|
+
std::shared_ptr<Client> client;
|
|
52
|
+
ObjectRequestHeader requestHeader;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
using ObjectRequestType = scaler::protocol::ObjectRequestHeader::ObjectRequestType;
|
|
56
|
+
using ObjectResponseType = scaler::protocol::ObjectResponseHeader::ObjectResponseType;
|
|
57
|
+
|
|
58
|
+
ymq::IOContext _ioContext;
|
|
59
|
+
std::shared_ptr<ymq::IOSocket> _ioSocket;
|
|
60
|
+
|
|
61
|
+
int onServerReadyReader;
|
|
62
|
+
int onServerReadyWriter;
|
|
63
|
+
|
|
64
|
+
ObjectManager objectManager;
|
|
65
|
+
|
|
66
|
+
// Some GET and DUPLICATE requests might be delayed if the referenced object isn't available yet.
|
|
67
|
+
std::map<ObjectID, std::vector<PendingRequest>> pendingRequests;
|
|
68
|
+
|
|
69
|
+
scaler::ymq::Logger _logger;
|
|
70
|
+
|
|
71
|
+
std::atomic<bool> _stopped;
|
|
72
|
+
|
|
73
|
+
std::vector<SendMessageFuture> _pendingSendMessageFuts;
|
|
74
|
+
|
|
75
|
+
void initServerReadyFds();
|
|
76
|
+
|
|
77
|
+
void setServerReadyFd();
|
|
78
|
+
|
|
79
|
+
void closeServerReadyFds();
|
|
80
|
+
|
|
81
|
+
void processRequests();
|
|
82
|
+
|
|
83
|
+
void processSetRequest(std::shared_ptr<Client> client, std::pair<ObjectRequestHeader, Bytes> request);
|
|
84
|
+
|
|
85
|
+
void processGetRequest(std::shared_ptr<Client> client, const ObjectRequestHeader& requestHeader);
|
|
86
|
+
|
|
87
|
+
void processDeleteRequest(std::shared_ptr<Client> client, ObjectRequestHeader& requestHeader);
|
|
88
|
+
|
|
89
|
+
void processDuplicateRequest(std::shared_ptr<Client> client, std::pair<ObjectRequestHeader, Bytes> request);
|
|
90
|
+
|
|
91
|
+
template <ObjectStorageMessage T>
|
|
92
|
+
void writeMessage(std::shared_ptr<Client> client, T& message, std::span<const unsigned char> payload)
|
|
93
|
+
{
|
|
94
|
+
// Send OSS header
|
|
95
|
+
auto messageBuffer = message.toBuffer();
|
|
96
|
+
ymq::Message ymqHeader {};
|
|
97
|
+
ymqHeader.address = Bytes(client->_identity);
|
|
98
|
+
ymqHeader.payload = Bytes((char*)messageBuffer.asBytes().begin(), messageBuffer.asBytes().size());
|
|
99
|
+
auto sendHeaderFuture = ymq::futureSendMessage(client->_ioSocket, std::move(ymqHeader));
|
|
100
|
+
|
|
101
|
+
if (!payload.data()) {
|
|
102
|
+
_pendingSendMessageFuts.emplace_back(std::move(sendHeaderFuture));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
ymq::Message ymqPayload {};
|
|
107
|
+
ymqPayload.address = Bytes(client->_identity);
|
|
108
|
+
ymqPayload.payload = Bytes((char*)payload.data(), payload.size());
|
|
109
|
+
auto sendPayloadFuture = ymq::futureSendMessage(client->_ioSocket, std::move(ymqPayload));
|
|
110
|
+
|
|
111
|
+
_pendingSendMessageFuts.emplace_back(std::move(sendHeaderFuture));
|
|
112
|
+
_pendingSendMessageFuts.emplace_back(std::move(sendPayloadFuture));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void sendGetResponse(
|
|
116
|
+
std::shared_ptr<Client> client,
|
|
117
|
+
const ObjectRequestHeader& requestHeader,
|
|
118
|
+
std::shared_ptr<const ObjectPayload> objectPtr);
|
|
119
|
+
|
|
120
|
+
void sendDuplicateResponse(std::shared_ptr<Client> client, const ObjectRequestHeader& requestHeader);
|
|
121
|
+
|
|
122
|
+
void optionallySendPendingRequests(const ObjectID& objectID, std::shared_ptr<const ObjectPayload> objectPtr);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
}; // namespace object_storage
|
|
126
|
+
}; // namespace scaler
|
|
Binary file
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#define PY_SSIZE_T_CLEAN
|
|
2
|
+
#include <Python.h>
|
|
3
|
+
|
|
4
|
+
#include "scaler/object_storage/object_storage_server.h"
|
|
5
|
+
|
|
6
|
+
extern "C" {
|
|
7
|
+
struct PyObjectStorageServer {
|
|
8
|
+
PyObject_HEAD scaler::object_storage::ObjectStorageServer server;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
static PyObject* PyObjectStorageServerNew(
|
|
12
|
+
PyTypeObject* type, [[maybe_unused]] PyObject* args, [[maybe_unused]] PyObject* kwargs)
|
|
13
|
+
{
|
|
14
|
+
PyObjectStorageServer* self;
|
|
15
|
+
self = (PyObjectStorageServer*)type->tp_alloc(type, 0);
|
|
16
|
+
return (PyObject*)self;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static int PyObjectStorageServerInit(PyObject* self, [[maybe_unused]] PyObject* args, [[maybe_unused]] PyObject* kwargs)
|
|
20
|
+
{
|
|
21
|
+
new (&((PyObjectStorageServer*)self)->server) scaler::object_storage::ObjectStorageServer();
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static void PyObjectStorageServerDealloc(PyObject* self)
|
|
26
|
+
{
|
|
27
|
+
((PyObjectStorageServer*)self)->server.~ObjectStorageServer();
|
|
28
|
+
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static PyObject* PyObjectStorageServerRun(PyObject* self, PyObject* args)
|
|
32
|
+
{
|
|
33
|
+
const char* addr;
|
|
34
|
+
int port;
|
|
35
|
+
const char* identity;
|
|
36
|
+
const char* log_level;
|
|
37
|
+
const char* log_format;
|
|
38
|
+
PyObject* logging_paths_tuple = nullptr;
|
|
39
|
+
|
|
40
|
+
if (!PyArg_ParseTuple(
|
|
41
|
+
args, "sisssO!", &addr, &port, &identity, &log_level, &log_format, &PyTuple_Type, &logging_paths_tuple))
|
|
42
|
+
return nullptr;
|
|
43
|
+
|
|
44
|
+
std::vector<std::string> logging_paths;
|
|
45
|
+
Py_ssize_t num_paths = PyTuple_Size(logging_paths_tuple);
|
|
46
|
+
for (Py_ssize_t i = 0; i < num_paths; ++i) {
|
|
47
|
+
PyObject* path_obj = PyTuple_GetItem(logging_paths_tuple, i);
|
|
48
|
+
if (!PyUnicode_Check(path_obj)) {
|
|
49
|
+
PyErr_SetString(PyExc_TypeError, "logging_paths must be a tuple of strings");
|
|
50
|
+
return nullptr;
|
|
51
|
+
}
|
|
52
|
+
logging_paths.push_back(PyUnicode_AsUTF8(path_obj));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
((PyObjectStorageServer*)self)
|
|
56
|
+
->server.run(addr, std::to_string(port), identity, log_level, log_format, std::move(logging_paths));
|
|
57
|
+
|
|
58
|
+
Py_RETURN_NONE;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static PyObject* PyObjectStorageServerWaitUntilReady(PyObject* self, [[maybe_unused]] PyObject* args)
|
|
62
|
+
{
|
|
63
|
+
((PyObjectStorageServer*)self)->server.waitUntilReady();
|
|
64
|
+
Py_RETURN_NONE;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static PyMethodDef PyObjectStorageServerMethods[] = {
|
|
68
|
+
{"run", PyObjectStorageServerRun, METH_VARARGS, "Run object storage server on address:port with logging config"},
|
|
69
|
+
{"wait_until_ready", PyObjectStorageServerWaitUntilReady, METH_NOARGS, "Wait until the server is ready"},
|
|
70
|
+
{nullptr, nullptr, 0, nullptr},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
static PyTypeObject PyObjectStorageServerType = {
|
|
74
|
+
.tp_name = "object_storage_server.ObjectStorageServer",
|
|
75
|
+
.tp_basicsize = sizeof(PyObjectStorageServer),
|
|
76
|
+
.tp_dealloc = (destructor)PyObjectStorageServerDealloc,
|
|
77
|
+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
|
78
|
+
.tp_doc = "ObjectStorageServer",
|
|
79
|
+
.tp_methods = PyObjectStorageServerMethods,
|
|
80
|
+
.tp_init = (initproc)PyObjectStorageServerInit,
|
|
81
|
+
.tp_new = PyObjectStorageServerNew,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
static PyModuleDef PyObjectStorageServerModule = {
|
|
85
|
+
.m_base = PyModuleDef_HEAD_INIT,
|
|
86
|
+
.m_name = "object_storage_server",
|
|
87
|
+
.m_size = -1,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
PyMODINIT_FUNC PyInit_object_storage_server(void)
|
|
91
|
+
{
|
|
92
|
+
PyObject* m;
|
|
93
|
+
if (PyType_Ready(&PyObjectStorageServerType) < 0)
|
|
94
|
+
return nullptr;
|
|
95
|
+
|
|
96
|
+
m = PyModule_Create(&PyObjectStorageServerModule);
|
|
97
|
+
if (m == nullptr)
|
|
98
|
+
return nullptr;
|
|
99
|
+
|
|
100
|
+
Py_INCREF(&PyObjectStorageServerType);
|
|
101
|
+
PyModule_AddObject(m, "ObjectStorageServer", (PyObject*)&PyObjectStorageServerType);
|
|
102
|
+
return m;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import capnp # noqa
|
|
2
|
+
|
|
3
|
+
import scaler.protocol.capnp.common_capnp as _common # noqa
|
|
4
|
+
import scaler.protocol.capnp.message_capnp as _message # noqa
|
|
5
|
+
import scaler.protocol.capnp.object_storage_capnp as _object_storage # noqa
|
|
6
|
+
import scaler.protocol.capnp.status_capnp as _status # noqa
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@0xf57f79ac88fab620;
|
|
2
|
+
|
|
3
|
+
enum TaskResultType {
|
|
4
|
+
success @0; # if submit and task is done and get result
|
|
5
|
+
failed @1; # if submit and task is failed on worker
|
|
6
|
+
failedWorkerDied @2; # if submit and worker died (only happened when scheduler keep_task=False)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
enum TaskCancelConfirmType {
|
|
10
|
+
canceled @0; # if cancel success
|
|
11
|
+
cancelFailed @1; # if cancel failed, this might happened if the task is in process
|
|
12
|
+
cancelNotFound @2; # if cancel cannot find such task
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
enum TaskTransition {
|
|
16
|
+
hasCapacity @0;
|
|
17
|
+
taskResultSuccess @1;
|
|
18
|
+
taskResultFailed @2;
|
|
19
|
+
taskResultWorkerDied @3;
|
|
20
|
+
taskCancel @4;
|
|
21
|
+
taskCancelConfirmCanceled @5;
|
|
22
|
+
taskCancelConfirmFailed @6;
|
|
23
|
+
taskCancelConfirmNotFound @7;
|
|
24
|
+
balanceTaskCancel @8;
|
|
25
|
+
workerDisconnect @9;
|
|
26
|
+
schedulerHasTask @10;
|
|
27
|
+
schedulerHasNoTask @11;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
enum TaskState {
|
|
31
|
+
inactive @0;
|
|
32
|
+
running @1;
|
|
33
|
+
canceling @2;
|
|
34
|
+
balanceCanceling @3;
|
|
35
|
+
success @4;
|
|
36
|
+
failed @5;
|
|
37
|
+
failedWorkerDied @6;
|
|
38
|
+
canceled @7;
|
|
39
|
+
canceledNotFound @8;
|
|
40
|
+
balanceCanceled @9;
|
|
41
|
+
workerDisconnecting @10;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
struct TaskCapability {
|
|
45
|
+
name @0 :Text; # the name of the capability provided by the worker/required by the task (e.g. "gpu" or "linux")
|
|
46
|
+
value @1 :Int64; # the quantity of the capability provided/required. Use -1 for quantity-less capabilities
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
struct ObjectMetadata {
|
|
50
|
+
objectIds @0 :List(Data);
|
|
51
|
+
objectTypes @1 :List(ObjectContentType);
|
|
52
|
+
objectNames @2 :List(Data);
|
|
53
|
+
|
|
54
|
+
enum ObjectContentType {
|
|
55
|
+
serializer @0;
|
|
56
|
+
object @1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
struct ObjectStorageAddress {
|
|
61
|
+
host @0 :Text;
|
|
62
|
+
port @1 :UInt16;
|
|
63
|
+
}
|