Skip to content

Commit 15b4304

Browse files
v0.7.8
1 parent 4d51c6a commit 15b4304

7 files changed

Lines changed: 68 additions & 31 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<img src="https://static.wikia.nocookie.net/arnelify/images/c/c8/Arnelify-logo-2024.png/revision/latest?cb=20240701012515" style="width:336px;" alt="Arnelify Logo" />
22

3-
![Arnelify Server for C++](https://img.shields.io/badge/Arnelify%20Server%20for%20C++-0.7.7-yellow) ![C++](https://img.shields.io/badge/C++-2b-red) ![G++](https://img.shields.io/badge/G++-14.2.0-blue) ![C-Lang](https://img.shields.io/badge/CLang-14.0.6-blue)
3+
![Arnelify Server for C++](https://img.shields.io/badge/Arnelify%20Server%20for%20C++-0.7.8-yellow) ![C++](https://img.shields.io/badge/C++-2b-red) ![G++](https://img.shields.io/badge/G++-14.2.0-blue) ![C-Lang](https://img.shields.io/badge/CLang-14.0.6-blue)
44

55
## 🚀 About
66
**Arnelify® Server for C++** - is a minimalistic dynamic library which is a powerful server written in C and C++.
@@ -59,6 +59,7 @@ You can find code examples <a href="https://github.com/arnelify/arnelify-server-
5959
| **SERVER_MAX_FILES**| Defines the maximum number of files in the form.|
6060
| **SERVER_MAX_FILES_SIZE_TOTAL_MB** | Defines the maximum total size of all files in the form.|
6161
| **SERVER_MAX_FILE_SIZE_MB**| Defines the maximum size of a single file in the form.|
62+
| **SERVER_NET_CHECK_FREQ_MS**| Network interface check frequency in milliseconds. The lower the value, the higher the CPU load.|
6263
| **SERVER_PORT**| Defines which port the server will listen on.|
6364
| **SERVER_THREAD_LIMIT**| Defines the maximum number of threads that will handle requests.|
6465
| **SERVER_QUEUE_LIMIT**| Defines the maximum size of the queue on the client socket.|
@@ -72,7 +73,7 @@ Join us to help improve this software, fix bugs or implement new functionality.
7273

7374

7475
## ⭐ Release Notes
75-
Version 0.7.7 - Minimalistic dynamic library
76+
Version 0.7.8 - Minimalistic dynamic library
7677

7778
We are excited to introduce the Arnelify Server for C++ dynamic library! Please note that this version is raw and still in active development.
7879

src/addon.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ Napi::Value server_http1_create(const Napi::CallbackInfo& args) {
140140
return env.Undefined();
141141
}
142142

143+
const bool hasNetCheckFreqMs = json.isMember("SERVER_NET_CHECK_FREQ_MS") &&
144+
json["SERVER_NET_CHECK_FREQ_MS"].isInt();
145+
if (!hasNetCheckFreqMs) {
146+
Napi::TypeError::New(env,
147+
"[Arnelify Server]: C++ error: "
148+
"'SERVER_NET_CHECK_FREQ_MS' is missing.")
149+
.ThrowAsJavaScriptException();
150+
return env.Undefined();
151+
}
152+
143153
const bool hasPort =
144154
json.isMember("SERVER_PORT") && json["SERVER_PORT"].isInt();
145155
if (!hasPort) {
@@ -150,8 +160,8 @@ Napi::Value server_http1_create(const Napi::CallbackInfo& args) {
150160
return env.Undefined();
151161
}
152162

153-
const bool hasThreadLimit =
154-
json.isMember("SERVER_THREAD_LIMIT") && json["SERVER_THREAD_LIMIT"].isInt();
163+
const bool hasThreadLimit = json.isMember("SERVER_THREAD_LIMIT") &&
164+
json["SERVER_THREAD_LIMIT"].isInt();
155165
if (!hasThreadLimit) {
156166
Napi::TypeError::New(env,
157167
"[Arnelify Server]: C++ error: "
@@ -179,7 +189,7 @@ Napi::Value server_http1_create(const Napi::CallbackInfo& args) {
179189
if (!hasSocketPath) json["SERVER_SOCKET_PATH"] = "/tmp/arnelify.sock";
180190

181191
UDSOpts udsOpts(json["SERVER_BLOCK_SIZE_KB"].asInt(),
182-
json["SERVER_SOCKET_PATH"].asString());
192+
json["SERVER_SOCKET_PATH"].asString());
183193
uds = new UDS(udsOpts);
184194

185195
Http1Opts opts(
@@ -190,7 +200,9 @@ Napi::Value server_http1_create(const Napi::CallbackInfo& args) {
190200
json["SERVER_MAX_FIELDS_SIZE_TOTAL_MB"].asInt(),
191201
json["SERVER_MAX_FILES"].asInt(),
192202
json["SERVER_MAX_FILES_SIZE_TOTAL_MB"].asInt(),
193-
json["SERVER_MAX_FILE_SIZE_MB"].asInt(), json["SERVER_PORT"].asInt(),
203+
json["SERVER_MAX_FILE_SIZE_MB"].asInt(),
204+
json["SERVER_NET_CHECK_FREQ_MS"].asInt(),
205+
json["SERVER_PORT"].asInt(),
194206
json["SERVER_THREAD_LIMIT"].asInt(), json["SERVER_QUEUE_LIMIT"].asInt(),
195207
json["SERVER_UPLOAD_DIR"].asString());
196208

@@ -351,9 +363,12 @@ Napi::Value uds_stop(const Napi::CallbackInfo& info) {
351363
}
352364

353365
Napi::Object Init(Napi::Env env, Napi::Object exports) {
354-
exports.Set("server_http1_create", Napi::Function::New(env, server_http1_create));
355-
exports.Set("server_http1_destroy", Napi::Function::New(env, server_http1_destroy));
356-
exports.Set("server_http1_start", Napi::Function::New(env, server_http1_start));
366+
exports.Set("server_http1_create",
367+
Napi::Function::New(env, server_http1_create));
368+
exports.Set("server_http1_destroy",
369+
Napi::Function::New(env, server_http1_destroy));
370+
exports.Set("server_http1_start",
371+
Napi::Function::New(env, server_http1_start));
357372
exports.Set("server_http1_stop", Napi::Function::New(env, server_http1_stop));
358373
exports.Set("uds_start", Napi::Function::New(env, uds_start));
359374
exports.Set("uds_stop", Napi::Function::New(env, uds_stop));

src/ffi.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ void server_http1_create(const char *cOpts) {
119119
exit(1);
120120
}
121121

122-
const bool hasThreadLimit =
123-
json.isMember("SERVER_THREAD_LIMIT") && json["SERVER_THREAD_LIMIT"].isInt();
122+
const bool hasThreadLimit = json.isMember("SERVER_THREAD_LIMIT") &&
123+
json["SERVER_THREAD_LIMIT"].isInt();
124124
if (!hasThreadLimit) {
125125
std::cout << "[Arnelify Server FFI]: C error: "
126126
"'SERVER_THREAD_LIMIT' is missing."
@@ -149,25 +149,24 @@ void server_http1_create(const char *cOpts) {
149149
json["SERVER_MAX_FIELDS_SIZE_TOTAL_MB"].asInt(),
150150
json["SERVER_MAX_FILES"].asInt(),
151151
json["SERVER_MAX_FILES_SIZE_TOTAL_MB"].asInt(),
152-
json["SERVER_MAX_FILE_SIZE_MB"].asInt(), json["SERVER_PORT"].asInt(),
152+
json["SERVER_MAX_FILE_SIZE_MB"].asInt(),
153+
json["SERVER_NET_CHECK_FREQ_MS"].asInt(), json["SERVER_PORT"].asInt(),
153154
json["SERVER_THREAD_LIMIT"].asInt(), json["SERVER_QUEUE_LIMIT"].asInt(),
154155
json["SERVER_UPLOAD_DIR"].asString());
155-
156156
http1 = new Http1(opts);
157157
}
158158

159159
void server_http1_destroy() { http1 = nullptr; }
160160

161161
void server_http1_handler(const char *(*cHandler)(const char *)) {
162-
http1->handler([cHandler](const Http1Req &req,
163-
Http1Res res) -> void {
162+
http1->handler([cHandler](const Http1Req &req, Http1Res res) -> void {
164163
Json::StreamWriterBuilder writer;
165164
writer["indentation"] = "";
166165
writer["emitUTF8"] = true;
167166

168167
const std::string request = Json::writeString(writer, req);
169168
const char *cReq = request.c_str();
170-
std::string cRes = cHandler(cReq);
169+
const char *cRes = cHandler(cReq);
171170

172171
Json::Value json;
173172
Json::CharReaderBuilder reader;
@@ -179,7 +178,6 @@ void server_http1_handler(const char *(*cHandler)(const char *)) {
179178
exit(1);
180179
}
181180

182-
cRes.clear();
183181
const bool hasCode = json.isMember("code");
184182
if (hasCode) {
185183
res->setCode(json["code"].asInt());

src/tcp1/http1/contracts/opts.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ struct Http1Opts final {
1515
const int HTTP1_MAX_FILES;
1616
const std::size_t HTTP1_MAX_FILES_SIZE_TOTAL_MB;
1717
const std::size_t HTTP1_MAX_FILE_SIZE_MB;
18+
const int HTTP1_NET_CHECK_FREQ_MS;
1819
const int HTTP1_PORT;
1920
const int HTTP1_THREAD_LIMIT;
2021
const int HTTP1_QUEUE_LIMIT;
2122
const std::filesystem::path HTTP1_UPLOAD_DIR;
2223

23-
Http1Opts(const bool &a, const int b, const std::string &c, const bool &g,
24+
Http1Opts(const bool &ae, const int b, const std::string &c, const bool &g,
2425
const bool &k, const int mfd, const int mfdst, const int mfl,
25-
const int mflst, const int mfls, const int p, const int tl,
26-
const int q, const std::string &u = "storage/upload")
27-
: HTTP1_ALLOW_EMPTY_FILES(a),
26+
const int mflst, const int mfls, const int n, const int p,
27+
const int tl, const int q, const std::string &u = "storage/upload")
28+
: HTTP1_ALLOW_EMPTY_FILES(ae),
2829
HTTP1_BLOCK_SIZE_KB(b),
2930
HTTP1_CHARSET(c),
3031
HTTP1_GZIP(g),
@@ -34,6 +35,7 @@ struct Http1Opts final {
3435
HTTP1_MAX_FILES(mfl),
3536
HTTP1_MAX_FILES_SIZE_TOTAL_MB(mflst),
3637
HTTP1_MAX_FILE_SIZE_MB(mfls),
38+
HTTP1_NET_CHECK_FREQ_MS(n),
3739
HTTP1_PORT(p),
3840
HTTP1_THREAD_LIMIT(tl),
3941
HTTP1_QUEUE_LIMIT(q),

src/tcp1/http1/index.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,15 @@ class Http1 {
126126

127127
while (!ON_RECEIVER) {
128128
const ssize_t bytesRead = recv(task->clientSocket, block, blockLen, 0);
129-
if (bytesRead == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
130-
delete[] block;
131-
this->asyncRead->addTask(task);
132-
return;
129+
// if (bytesRead == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
130+
// delete[] block;
131+
// this->asyncRead->addTask(task);
132+
// return;
133+
// }
134+
135+
if (bytesRead > 0) {
136+
ON_RECEIVER = task->receiver->onBlock(block, bytesRead);
133137
}
134-
135-
ON_RECEIVER = task->receiver->onBlock(block, bytesRead);
136138
}
137139

138140
delete[] block;
@@ -182,6 +184,7 @@ class Http1 {
182184

183185
sockaddr_in clientAddr;
184186
socklen_t clientLen = sizeof(clientAddr);
187+
const int acceptDelay = this->opts.HTTP1_NET_CHECK_FREQ_MS;
185188
const Http1TaskOpts opts(
186189
this->opts.HTTP1_ALLOW_EMPTY_FILES, this->opts.HTTP1_BLOCK_SIZE_KB,
187190
this->opts.HTTP1_CHARSET, this->opts.HTTP1_GZIP,
@@ -211,6 +214,10 @@ class Http1 {
211214
break;
212215
}
213216

217+
if (acceptDelay) {
218+
std::this_thread::sleep_for(std::chrono::milliseconds(acceptDelay));
219+
}
220+
214221
continue;
215222
}
216223

src/tcp1/http1/io/index.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ class Http1IO {
4444
if (this->isRunning) return;
4545
this->isRunning = true;
4646

47-
for (int i = 0; this->threadLimit > i; ++i) {
47+
for (int i = 0; this->threadLimit > i; i++) {
4848
std::thread thread([this]() {
4949
while (true) {
5050
Http1Task* task = nullptr;
5151
{
5252
std::unique_lock<std::mutex> lock(this->mtx);
53-
cv.wait(lock, [this]() { return !this->queue.empty() && this->isRunning; });
53+
cv.wait(lock, [this]() { return !this->queue.empty() || !this->isRunning; });
5454
if (!this->isRunning) break;
5555

5656
task = this->queue.front();

src/tests/index.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,22 @@
88
#include "../index.h"
99

1010
int main(int argc, char* argv[]) {
11-
Http1Opts http1Opts(true, 64, "UTF-8", true, true, 1024, 20, 1, 60, 60, 3001,
12-
3, 1024, "./storage/upload");
11+
Http1Opts http1Opts(
12+
/* SERVER_ALLOW_EMPTY_FILES */ true,
13+
/* SERVER_BLOCK_SIZE_KB */ 64,
14+
/* SERVER_CHARSET */ "UTF-8",
15+
/* SERVER_GZIP */ true,
16+
/* SERVER_KEEP_EXTENSIONS */ true,
17+
/* SERVER_MAX_FIELDS */ 1024,
18+
/* SERVER_MAX_FIELDS_SIZE_TOTAL_MB */ 20,
19+
/* SERVER_MAX_FILES */ 1,
20+
/* SERVER_MAX_FILES_SIZE_TOTAL_MB */ 60,
21+
/* SERVER_MAX_FILE_SIZE_MB */ 60,
22+
/* SERVER_NET_CHECK_FREQ_MS */ 50,
23+
/* SERVER_PORT */ 3001,
24+
/* SERVER_THREAD_LIMIT */ 5,
25+
/* SERVER_QUEUE_LIMIT */ 1024,
26+
/* SERVER_UPLOAD_DIR */ "./storage/upload");
1327

1428
Http1 http1(http1Opts);
1529
http1.handler([](const Http1Req& req, Http1Res res) {

0 commit comments

Comments
 (0)