Skip to content

Commit 431f643

Browse files
v0.7.8
1 parent b28adcc commit 431f643

File tree

9 files changed

+58
-33
lines changed

9 files changed

+58
-33
lines changed

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 Python](https://img.shields.io/badge/Arnelify%20Server%20for%20Python-0.7.7-yellow) ![C++](https://img.shields.io/badge/C++-2b-red) ![G++](https://img.shields.io/badge/G++-14.2.0-blue) ![Python](https://img.shields.io/badge/Python-3.11.2-blue) ![Nuitka](https://img.shields.io/badge/Nuitka-2.6.4-blue)
3+
![Arnelify Server for Python](https://img.shields.io/badge/Arnelify%20Server%20for%20Python-0.7.8-yellow) ![C++](https://img.shields.io/badge/C++-2b-red) ![G++](https://img.shields.io/badge/G++-14.2.0-blue) ![Python](https://img.shields.io/badge/Python-3.11.2-blue) ![Nuitka](https://img.shields.io/badge/Nuitka-2.6.4-blue)
44

55
## 🚀 About
66
**Arnelify® Server for Python** - is a minimalistic dynamic library which is a powerful server written in C and C++.
@@ -61,6 +61,7 @@ You can find code examples <a href="https://github.com/arnelify/arnelify-server-
6161
| **SERVER_MAX_FILES**| Defines the maximum number of files in the form.|
6262
| **SERVER_MAX_FILES_SIZE_TOTAL_MB** | Defines the maximum total size of all files in the form.|
6363
| **SERVER_MAX_FILE_SIZE_MB**| Defines the maximum size of a single file in the form.|
64+
| **SERVER_NET_CHECK_FREQ_MS**| Network interface check frequency in milliseconds. The lower the value, the higher the CPU
6465
| **SERVER_PORT**| Defines which port the server will listen on.|
6566
| **SERVER_THREAD_LIMIT**| Defines the maximum number of threads that will handle requests.|
6667
| **SERVER_QUEUE_LIMIT**| Defines the maximum size of the queue on the client socket.|
@@ -73,7 +74,7 @@ This software is licensed under the <a href="https://github.com/arnelify/arnelif
7374
Join us to help improve this software, fix bugs or implement new functionality. Active participation will help keep the software up-to-date, reliable, and aligned with the needs of its users.
7475

7576
## ⭐ Release Notes
76-
Version 0.7.7 - Minimalistic dynamic library
77+
Version 0.7.8 - Minimalistic dynamic library
7778

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

arnelify_server/index.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def __init__(self, opts: dict):
2828
"SERVER_MAX_FILES",
2929
"SERVER_MAX_FILES_SIZE_TOTAL_MB",
3030
"SERVER_MAX_FILE_SIZE_MB",
31+
"SERVER_NET_CHECK_FREQ_MS",
3132
"SERVER_PORT",
3233
"SERVER_QUEUE_LIMIT"
3334
]
@@ -88,11 +89,11 @@ def server_thread():
8889
self.lib.server_http1_start(cCallback)
8990

9091
thread = threading.Thread(target=server_thread)
91-
thread.daemon = True # Allows the thread to exit when the program exits
92+
thread.daemon = True
9293
thread.start()
9394

9495
try:
95-
thread.join() # This will block and keep the program running until the background thread finishes
96+
thread.join()
9697
except KeyboardInterrupt:
9798
exit(1)
9899

arnelify_server/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));

arnelify_server/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());

arnelify_server/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),

arnelify_server/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

arnelify_server/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();

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
setup(
1313
name="arnelify_server",
14-
version="0.7.7",
14+
version="0.7.8",
1515
author="Arnelify",
1616
description="Minimalistic dynamic library which is a powerful server written in C and C++.",
1717
url='https://github.com/arnelify/arnelify-server-python',

tests/index.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ def main():
1515
"SERVER_MAX_FILES": 1,
1616
"SERVER_MAX_FILES_SIZE_TOTAL_MB": 60,
1717
"SERVER_MAX_FILE_SIZE_MB": 60,
18+
"SERVER_NET_CHECK_FREQ_MS": 50,
1819
"SERVER_PORT": 3001,
19-
"SERVER_THREAD_LIMIT": 1,
20+
"SERVER_THREAD_LIMIT": 5,
2021
"SERVER_QUEUE_LIMIT": 1024,
2122
"SERVER_UPLOAD_DIR": "storage/upload"
2223
})

0 commit comments

Comments
 (0)