Open kyrylolvov opened 1 month ago
Is there a solution which doesn't involve killing the child processes? Rather just killing crow app.
@gittiver Any idea on how to solve this? Somehow the .stop() doesn't fully close the file descriptors (at least in a child process).
Not really.
There is a while(1) loop after stop() in createResource. What about the used middleware, maybe remove it temporarily to check if it works then? and do you use the master branch or the release?
Not really.
There is a while(1) loop after stop() in createResource. What about the used middleware, maybe remove it temporarily to check if it works then? and do you use the master branch or the release?
The used middleware is just setting Content-Type header to json.
#pragma once
#include "crow.h"
namespace middleware {
struct RestApiMiddleware {
struct context {};
void before_handle(crow::request &req, crow::response &res, context &ctx) {}
void after_handle(crow::request &req, crow::response &res, context &ctx) {
res.set_header("Content-Type", "application/json");
}
};
} // namespace middleware
I have just updated Crow to latest release, and it's still not fully stopped in the child process.
I wrote this function, and calling it in the child process actually fixes the issue.
#include "utilities/common.h"
void utilities::CommonUtilities::cleanUpSocket(int port) {
// Stop the application
app.stop();
// Iterate through all possible file descriptors
for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd) {
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
// Try to get the socket name for the current file descriptor
if (getsockname(fd, (struct sockaddr *)&addr, &len) == 0) {
// Check if the socket is an IPv4 socket and matches the given port
if (addr.sin_family == AF_INET && ntohs(addr.sin_port) == port) {
std::cout << "Closed socket on port " << port << " in child process" << std::endl;
// Close the socket
close(fd);
// Exit the loop as we've found and closed the desired socket
break;
}
}
}
}
Maybe I am wrong but you are closing the server in the request_handler but after that the :: after_handle of the middleware is called by the app, I am not shure, possibly this is the reason why the server does not stop completely.
Could you check without the middlewar, if the server stops correctly?
btw. you can directly return a json object from the handler, then the content-type will be set correctly already.
Maybe I am wrong but you are closing the server in the request_handler but after that the :: after_handle of the middleware is called by the app, I am not shure, possibly this is the reason why the server does not stop completely.
Could you check without the middlewar, if the server stops correctly?
Yeah, I just tried removing middleware and calling app.stop()
in the child, without the function to close sockets manually. The logs that it has been closed appear, but when I exit the program, ss -ln src :18080
shows that the port is still taken.
btw. you can directly return a json object from the handler, then the content-type will be set correctly already.
But if I just return the json object directly, how do I change the status code of the response? Couldn't find that in the examples.
Hello! Is there a way to somehow kill crow inside a child process or not let it inherit?
This is my code. Even though logs for closing app are printed in the console, when I exit the app, the port is still taken.