Skip to content

Commit 16471e5

Browse files
committed
args, server: Simplify and fix bugs
User-facing improvements * Bare `./tts-cli -p` no longer crashes * Merged --use-espeak into just omitting --phonemizer-path * Errors are now text/plain instead of JSON * We don't need to write so much error handling code * OpenAI compatibility isn't important for errors * Server startup page now only disappears after everything loads * Fixed buffer reuse race condition between audio generation and HTTP output * conditional_prompt is now a JSON key, no longer an HTTP endpoint * This lifts the limitation of 1 worker thread Internal improvements * struct arg is now pointer-free and like a regular std::variant * `args["my-arg"]` (+ cast rarely) should feel like Python * Deduplicated args.add, updated .md, unified descriptions * Converted many copies to pass-by-reference * Less related files are left for the code style PR * Cached the only 2 JSON success responses * The main thread is now simply the listener thread, not a worker * Timeouts are now also enforced on the HTTP threads * Removed simple_response_map to avoid collisions and thread contention * simple_text_prompt_task is pooled and no longer leaked every request * This is the first time we're freeing runner memory
1 parent c443aae commit 16471e5

31 files changed

+840
-1271
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ We are currently [working on upstreaming some of these operations inorder to dep
6060
#### Build:
6161

6262
Assuming that the above requirements are met the library and basic CLI example can be built by running the following command in the repository's base directory:
63-
```commandline
63+
```bash
6464
cmake -B build
6565
cmake --build build --config Release
6666
```

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
add_library(examples_common
44
args.cpp
55
args.h
6+
args_common.cpp
7+
args_common.h
68
audio_file.h
79
)
810
target_include_directories(examples_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

examples/args.cpp

Lines changed: 55 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,76 @@
11
#include "args.h"
22

3-
std::string arg::help_text() {
4-
std::string htxt = full_name;
5-
if (abbreviation != "") {
6-
htxt += " (" + abbreviation + ")";
3+
#include <iostream>
4+
#include <sstream>
5+
6+
void arg::print_help() const {
7+
cout << "--" << full_name;
8+
if (*abbreviation) {
9+
cout << " (-" << abbreviation << ")";
710
}
8-
htxt += ":\n ";
9-
if (description != "") {
10-
htxt += description + "\n";
11+
if (*description) {
12+
cout << (required ? ":\n (REQUIRED) " : ":\n (OPTIONAL) ") << description << ".\n";
1113
} else {
12-
htxt += "is a " + (std::string)(required ? "required " : "optional ") + "parameter.\n";
14+
cout << (required ? " is a required parameter.\n" : " is an optional parameter.\n");
1315
}
14-
return htxt;
1516
}
1617

17-
int string_arg::parse(int argc, const char ** argv) {
18+
void arg::parse(span<str> & argv) {
1819
required = false;
19-
value.assign(argv[0]);
20-
return 1;
21-
}
22-
23-
int int_arg::parse(int argc, const char ** argv) {
24-
if (required) {
25-
required = false;
20+
if (const auto bool_param{get_if<bool>(&value)}) {
21+
*bool_param = true;
22+
return;
23+
}
24+
if (argv.empty()) {
25+
fprintf(stderr, "The option '--%s' requires an argument\n", full_name);
26+
exit(1);
27+
}
28+
const str a = argv[0];
29+
argv = argv.subspan(1);
30+
if (const auto string_param{get_if<str>(&value)}) {
31+
*string_param = a;
32+
} else if (const auto int_param{get_if<int>(&value)}) {
33+
istringstream{a} >> *int_param;
34+
} else if (const auto float_param{get_if<float>(&value)}) {
35+
istringstream{a} >> *float_param;
2636
}
27-
int val = atoi(argv[0]);
28-
*value = val;
29-
return 1;
3037
}
3138

32-
int float_arg::parse(int argc, const char ** argv) {
33-
if (required) {
34-
required = false;
35-
}
36-
float val = strtof(argv[0], nullptr);
37-
*value = val;
38-
return 1;
39-
}
40-
41-
void arg_list::help() {
42-
std::string help_text = "";
43-
for (auto arg : fargs) {
44-
help_text += arg.help_text();
45-
}
46-
for (auto arg : iargs) {
47-
help_text += arg.help_text();
48-
49-
}
50-
for (auto arg : bargs) {
51-
help_text += arg.help_text();
52-
53-
}
54-
for (auto arg : sargs) {
55-
help_text += arg.help_text();
56-
57-
}
58-
fprintf(stdout, "%s", help_text.c_str());
59-
}
60-
61-
void arg_list::validate() {
62-
for (auto arg : fargs) {
63-
if (arg.required) {
64-
fprintf(stderr, "argument '%s' is required.\n", arg.full_name.c_str());
39+
void arg_list::parse(int argc, str argv_[]) {
40+
TTS_ASSERT(argc);
41+
span<str> argv{argv_, static_cast<size_t>(argc)};
42+
argv = argv.subspan(1);
43+
while (!argv.empty()) {
44+
str name{argv[0]};
45+
if (*name != '-') {
46+
fprintf(stderr, "Only named arguments are supported\n");
6547
exit(1);
6648
}
67-
}
68-
for (auto arg : iargs) {
69-
if (arg.required) {
70-
fprintf(stderr, "argument '%s' is required.\n", arg.full_name.c_str());
71-
exit(1);
49+
++name;
50+
const map<sv, size_t> * lookup = &abbreviations;
51+
if (*name == '-') {
52+
++name;
53+
lookup = &full_names;
54+
if (name == "help"sv) {
55+
for (const size_t i : full_names | views::values) {
56+
args[i].print_help();
57+
}
58+
exit(0);
59+
}
7260
}
73-
}
74-
for (auto arg : bargs) {
75-
if (arg.required) {
76-
fprintf(stderr, "argument '%s' is required.\n", arg.full_name.c_str());
61+
const auto found = lookup->find(sv{name});
62+
if (found == lookup->end()) {
63+
fprintf(stderr, "argument '%s' is not a valid argument. "
64+
"Call '--help' for information on all valid arguments.\n", argv[0]);
7765
exit(1);
7866
}
67+
argv = argv.subspan(1);
68+
args[found->second].parse(argv);
7969
}
80-
for (auto arg : sargs) {
81-
if (arg.required) {
82-
fprintf(stderr, "argument '%s' is required.\n", arg.full_name.c_str());
70+
for (const arg & x : args) {
71+
if (x.required) {
72+
fprintf(stderr, "argument '--%s' is required.\n", x.full_name);
8373
exit(1);
8474
}
8575
}
8676
}
87-
88-
void arg_list::parse(int argc, const char ** argv) {
89-
int current_arg = 1;
90-
while (current_arg < argc) {
91-
std::string name(argv[current_arg]);
92-
if (name == "--help") {
93-
for_help = true;
94-
return;
95-
}
96-
current_arg += 1;
97-
current_arg += find_and_parse(name, argc - current_arg, argv + current_arg);
98-
}
99-
}
100-
101-
int arg_list::find_and_parse(std::string name, int argc, const char ** argv) {
102-
for (int i = 0; i < fargs.size(); i++) {
103-
if (fargs[i].full_name == name || fargs[i].abbreviation == name) {
104-
return fargs[i].parse(argc, argv);
105-
}
106-
}
107-
for (int i = 0; i < iargs.size(); i++) {
108-
if (iargs[i].full_name == name || iargs[i].abbreviation == name) {
109-
return iargs[i].parse(argc, argv);
110-
}
111-
}
112-
for (int i = 0; i < bargs.size(); i++) {
113-
if (bargs[i].full_name == name || bargs[i].abbreviation == name) {
114-
bargs[i].value = !bargs[i].value;
115-
bargs[i].required = false;
116-
return 0;
117-
}
118-
119-
}
120-
for (int i = 0; i < sargs.size(); i++) {
121-
if (sargs[i].full_name == name || sargs[i].abbreviation == name) {
122-
return sargs[i].parse(argc, argv);
123-
}
124-
}
125-
fprintf(stderr, "argument '%s' is not a valid argument. Call '--help' for information on all valid arguments.\n", name.c_str());
126-
exit(1);
127-
}
128-
129-
std::string arg_list::get_string_param(std::string full_name) {
130-
for (auto arg : sargs) {
131-
if (arg.full_name == full_name) {
132-
return arg.value;
133-
}
134-
}
135-
return "";
136-
}
137-
138-
int * arg_list::get_int_param(std::string full_name) {
139-
for (auto arg : iargs) {
140-
if (arg.full_name == full_name) {
141-
return arg.value;
142-
}
143-
}
144-
return nullptr;
145-
}
146-
147-
float * arg_list::get_float_param(std::string full_name) {
148-
for (auto arg : fargs) {
149-
if (arg.full_name == full_name) {
150-
return arg.value;
151-
}
152-
}
153-
return nullptr;
154-
}
155-
156-
bool arg_list::get_bool_param(std::string full_name) {
157-
for (auto arg : bargs) {
158-
if (arg.full_name == full_name) {
159-
return arg.value;
160-
}
161-
}
162-
return false;
163-
}
164-

0 commit comments

Comments
 (0)