Skip to content

Commit 508c420

Browse files
authored
feat(interactive): Introduce max_content_size for admin_service (#4491)
As titled.
1 parent d3ac669 commit 508c420

File tree

19 files changed

+164
-53
lines changed

19 files changed

+164
-53
lines changed

.github/workflows/flex-interactive.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,8 @@ jobs:
9595
GS_TEST_DIR: /tmp/gstest
9696
run: |
9797
# launch service: ${COORDINATOR_PORT} for coordinator http port; ${CYPHER_PORT} for cypher port;
98-
cat >> ${GITHUB_WORKSPACE}/flex/tests/hqps/interactive_config_test.yaml << EOF
99-
coordinator:
100-
max_content_length: 1048576 # 1MB
101-
EOF
98+
# replace max_content_length to 1MB
99+
sed -i 's/max_content_length: .*/max_content_length: 1MB/g' ${GITHUB_WORKSPACE}/flex/tests/hqps/interactive_config_test.yaml
102100
gsctl instance deploy --type interactive --image-registry graphscope --image-tag latest --cypher-port ${CYPHER_PORT} \
103101
--coordinator-port ${COORDINATOR_PORT} --config ${GITHUB_WORKSPACE}/flex/tests/hqps/interactive_config_test.yaml \
104102
--admin-port 7778 --storedproc-port 10001

coordinator/gscoordinator/coordinator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from gscoordinator.flex.core.config import SOLUTION
3838
from gscoordinator.flex.encoder import JSONEncoder
3939
from gscoordinator.monitor import Monitor
40+
from gscoordinator.utils import human_readable_to_bytes
4041

4142
logger = logging.getLogger("graphscope")
4243

@@ -134,7 +135,9 @@ def start_http_service(config):
134135
initialize_client_wrapper(config)
135136
app = connexion.App(__name__, specification_dir="./flex/openapi/")
136137
app.app.json_encoder = JSONEncoder
137-
app.app.config["MAX_CONTENT_LENGTH"] = config.coordinator.max_content_length
138+
app.app.config["MAX_CONTENT_LENGTH"] = human_readable_to_bytes(
139+
config.coordinator.max_content_length
140+
)
138141
app.add_api(
139142
"openapi.yaml",
140143
arguments={"title": "GraphScope FLEX HTTP SERVICE API"},

coordinator/gscoordinator/utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,3 +2170,36 @@ def replace_string_in_dict(dict_obj, old, new):
21702170
elif isinstance(dict_obj, str):
21712171
return dict_obj.replace(old, new)
21722172
return dict_obj
2173+
2174+
2175+
# Reference: https://gist.github.com/beugley/ccd69945346759eb6142272a6d69b4e0
2176+
def human_readable_to_bytes(size):
2177+
"""Given a human-readable byte string (e.g. 2G, 30M, 20K),
2178+
return the number of bytes. Will raise an exception if the argument has
2179+
unexpected form.
2180+
"""
2181+
# Try to parse the size as if the unit was coded on 1 char.
2182+
try:
2183+
numeric_size = float(size[:-1])
2184+
unit = size[-1]
2185+
except ValueError:
2186+
try:
2187+
# Try to parse the size as if the unit was coded on 2 chars.
2188+
numeric_size = float(size[:-2])
2189+
unit = size[-2:-1]
2190+
except ValueError:
2191+
raise ValueError("Can't convert %r to bytes" % size)
2192+
2193+
unit = unit.upper()
2194+
2195+
# Now we have a numeric value and a unit. Check the unit and convert to bytes.
2196+
if unit == "G":
2197+
bytes = numeric_size * 1073741824
2198+
elif unit == "M":
2199+
bytes = numeric_size * 1048576
2200+
elif unit == "K":
2201+
bytes = numeric_size * 1024
2202+
else:
2203+
bytes = numeric_size
2204+
2205+
return int(bytes)

docs/flex/interactive/configuration.md

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,6 @@ gsctl instance deploy --type interactive --config ./interactive_config.yaml
6161
Please be aware that you're not required to configure every option. Simply adjust the settings that are relevant to your needs. Any options left unconfigured will automatically adopt their default values, as detailed in the following sections.
6262
```
6363

64-
#### Customize Coordinator Service Configuration
65-
66-
When deploying Interactive, a supplementary service called the Coordinator is also initiated. This service functions similarly to the `ApiServer` in Kubernetes, providing users with a consistent and standardized set of APIs to interact with the GraphScope platform.
67-
You could also customize the configuration for coordinator service, just put the configuration in `coordinator` section.
68-
69-
An example of a coordinator related configuration is as follows:
70-
71-
```yaml
72-
coordinator:
73-
max_content_length: 5242880 # maximum bytes of content the coordinator can handle
74-
```
75-
76-
For more details, consult [config.py](https://github.com/alibaba/GraphScope/blob/main/python/graphscope/config.py).
77-
7864

7965
##### Sample Configuration
8066
Here's a glimpse of what a typical YAML configuration file might look like:
@@ -134,7 +120,7 @@ In this following table, we use the `.` notation to represent the hierarchy with
134120
| compiler.planner.rules.NotMatchToAntiJoinRule | N/A | An optimization rule that transforms a "not exist" pattern into an anti-join operation | 0.0.1 |
135121
| compiler.query_timeout | 3000000 | The maximum time for compiler to wait engine's reply, in `ms` | 0.0.3 |
136122
| http_service.sharding_mode | exclusive | The sharding mode for http service, In exclusive mode, one shard is reserved exclusively for service admin request. In cooperative, both query request and admin request could be served by any shard. | 0.5 |
137-
| coordinator.max_content_length | 1073741824 | The maximum length of a http request that coordinator could handle | 0.5 |
123+
| http_service.max_content_length | 1GB | The maximum length of a http request that admin http service could handle | 0.5 |
138124

139125
#### TODOs
140126

flex/engines/http_server/actor/admin_actor.act.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,9 +1345,9 @@ seastar::future<admin_query_result> admin_actor::run_get_graph_statistic(
13451345
}
13461346

13471347
seastar::future<admin_query_result> admin_actor::upload_file(
1348-
query_param&& query_param) {
1349-
auto& content = query_param.content;
1350-
auto upload_res = WorkDirManipulator::CreateFile(content);
1348+
graph_management_param&& query_param) {
1349+
auto upload_res = WorkDirManipulator::CreateFile(query_param.content.first,
1350+
query_param.content.second);
13511351
if (upload_res.ok()) {
13521352
auto value = upload_res.value();
13531353
return seastar::make_ready_future<admin_query_result>(

flex/engines/http_server/actor/admin_actor.act.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class ANNOTATION(actor:impl) admin_actor : public hiactor::actor {
7272

7373
seastar::future<admin_query_result> ANNOTATION(actor:method) run_get_graph_statistic(query_param&& param);
7474

75-
seastar::future<admin_query_result> ANNOTATION(actor:method) upload_file(query_param&& param);
75+
seastar::future<admin_query_result> ANNOTATION(actor:method) upload_file(graph_management_param&& file_name_content);
7676

7777
// DECLARE_RUN_QUERIES;
7878
/// Declare `do_work` func here, no need to implement.

flex/engines/http_server/graph_db_service.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ ServiceConfig::ServiceConfig()
4848
metadata_store_type_(gs::MetadataStoreType::kLocalFile),
4949
log_level(DEFAULT_LOG_LEVEL),
5050
verbose_level(DEFAULT_VERBOSE_LEVEL),
51-
sharding_mode(DEFAULT_SHARDING_MODE) {}
51+
sharding_mode(DEFAULT_SHARDING_MODE),
52+
admin_svc_max_content_length(DEFAULT_MAX_CONTENT_LENGTH) {}
5253

5354
const std::string GraphDBService::DEFAULT_GRAPH_NAME = "modern_graph";
5455
const std::string GraphDBService::DEFAULT_INTERACTIVE_HOME = "/opt/flex/";
@@ -121,7 +122,8 @@ void GraphDBService::init(const ServiceConfig& config) {
121122
config.enable_adhoc_handler);
122123
if (config.start_admin_service) {
123124
admin_hdl_ = std::make_unique<admin_http_handler>(
124-
config.admin_port, config.get_exclusive_shard_id());
125+
config.admin_port, config.get_exclusive_shard_id(),
126+
config.admin_svc_max_content_length);
125127
}
126128

127129
initialized_.store(true);

flex/engines/http_server/graph_db_service.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct ServiceConfig {
4747
0; // 0 = INFO, 1 = WARNING, 2 = ERROR, 3 = FATAL
4848
static constexpr const ShardingMode DEFAULT_SHARDING_MODE =
4949
ShardingMode::EXCLUSIVE;
50+
static constexpr const uint32_t DEFAULT_MAX_CONTENT_LENGTH =
51+
1024 * 1024 * 1024; // 1GB
5052

5153
// Those has default value
5254
uint32_t bolt_port;
@@ -80,7 +82,8 @@ struct ServiceConfig {
8082

8183
// Those has not default value
8284
std::string default_graph;
83-
std::string engine_config_path; // used for codegen.
85+
std::string engine_config_path; // used for codegen.
86+
size_t admin_svc_max_content_length; // max content length for admin service.
8487

8588
ServiceConfig();
8689

@@ -95,6 +98,20 @@ struct ServiceConfig {
9598
}
9699
}
97100

101+
void set_admin_svc_max_content_length(size_t max_content_length) {
102+
this->admin_svc_max_content_length = max_content_length;
103+
}
104+
105+
void set_admin_svc_max_content_length(const std::string& max_content_length) {
106+
auto val = gs::human_readable_to_bytes(max_content_length);
107+
if (val == 0) {
108+
LOG(ERROR) << "Invalid max_content_length: " << max_content_length << ", "
109+
<< "use default value: " << DEFAULT_MAX_CONTENT_LENGTH;
110+
val = DEFAULT_MAX_CONTENT_LENGTH;
111+
}
112+
set_admin_svc_max_content_length(val);
113+
}
114+
98115
int32_t get_exclusive_shard_id() const {
99116
return sharding_mode == ShardingMode::EXCLUSIVE ? shard_num - 1 : -1;
100117
}
@@ -286,6 +303,12 @@ struct convert<server::ServiceConfig> {
286303
service_config.set_sharding_mode(sharding_mode);
287304
VLOG(1) << "sharding_mode: " << sharding_mode;
288305
}
306+
if (http_service_node["max_content_length"]) {
307+
service_config.set_admin_svc_max_content_length(
308+
http_service_node["max_content_length"].as<std::string>());
309+
LOG(INFO) << "max_content_length: "
310+
<< service_config.admin_svc_max_content_length;
311+
}
289312
} else {
290313
LOG(ERROR) << "Fail to find http_service configuration";
291314
return false;

flex/engines/http_server/handler/admin_http_handler.cc

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ class admin_file_upload_handler_impl : public seastar::httpd::handler_base {
9898
std::move(results));
9999
} else {
100100
return admin_actor_refs_[dst_executor]
101-
.upload_file(
102-
query_param{std::move(file_name_and_contents[cur_ind].second)})
101+
.upload_file(graph_management_param{
102+
std::move(file_name_and_contents[cur_ind])})
103103
.then_wrapped([this, dst_executor, cur_ind,
104104
file_name_and_contents =
105105
std::move(file_name_and_contents),
@@ -165,8 +165,8 @@ class admin_file_upload_handler_impl : public seastar::httpd::handler_base {
165165
VLOG(10) << "filenames: " << gs::to_string(filenames);
166166
VLOG(10) << "content types" << gs::to_string(content_types);
167167
std::vector<std::pair<seastar::sstring, seastar::sstring>> res;
168-
for (size_t i = 0; i < names.size(); ++i) {
169-
res.emplace_back(names[i], contents[i]);
168+
for (size_t i = 0; i < filenames.size(); ++i) {
169+
res.emplace_back(filenames[i], contents[i]);
170170
}
171171
return res;
172172
}
@@ -642,15 +642,22 @@ class admin_http_job_handler_impl : public seastar::httpd::handler_base {
642642
};
643643

644644
admin_http_handler::admin_http_handler(uint16_t http_port,
645-
int32_t exclusive_shard_id)
646-
: http_port_(http_port), exclusive_shard_id_(exclusive_shard_id) {}
645+
int32_t exclusive_shard_id,
646+
size_t max_content_length)
647+
: http_port_(http_port),
648+
exclusive_shard_id_(exclusive_shard_id),
649+
max_content_length_(max_content_length) {}
647650

648651
void admin_http_handler::start() {
649652
auto fut = seastar::alien::submit_to(
650653
*seastar::alien::internal::default_instance, 0, [this] {
651654
return server_.start()
652655
.then([this] { return set_routes(); })
653-
.then([this] { return server_.listen(http_port_); })
656+
.then([this] {
657+
server_.server().local().set_content_length_limit(
658+
max_content_length_);
659+
return server_.listen(http_port_);
660+
})
654661
.then([this] {
655662
fmt::print(
656663
"HQPS admin http handler is listening on port {} ...\n",

flex/engines/http_server/handler/admin_http_handler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ namespace server {
2828
class InteractiveAdminService;
2929
class admin_http_handler {
3030
public:
31-
admin_http_handler(uint16_t http_port, int32_t exclusive_shard_id);
31+
admin_http_handler(uint16_t http_port, int32_t exclusive_shard_id,
32+
size_t max_content_length);
3233

3334
void start();
3435
void stop();
@@ -39,6 +40,7 @@ class admin_http_handler {
3940
private:
4041
const uint16_t http_port_;
4142
int32_t exclusive_shard_id_; // -1 means not exclusive
43+
size_t max_content_length_;
4244
seastar::httpd::http_server_control server_;
4345
};
4446

0 commit comments

Comments
 (0)