Fix issue with clean, implement process management

master
teknomunk 10 months ago
parent 563d1ee2ea
commit fc604be2ad

@ -1,4 +1,4 @@
#!/bin/bash
[[ -f src.a ]] && rm src.a
[[ -f obj/apogee.a ]] && rm obj/apogee.a
find ./obj -type f | grep -E '\.o$' | xargs -I'{}' rm '{}'

@ -32,6 +32,7 @@ struct app_args* app_args_new( int argc, char** argv )
args->port = 9053;
args->addr = strdup("0.0.0.0");
args->tor_socks_port = 9123;
args->section = -1;
json_read_object_layout_from_file( "data/server.json", app_args_layout, args );

@ -1 +1 @@
Subproject commit dce2da6feffd68bfb094ef3776371b2b42dbd2a5
Subproject commit 9465f2748facb2d38d8cfb6157a30f8958526180

@ -6,22 +6,13 @@
#include <signal.h>
#include <sys/prctl.h>
#include "http/server/server.h"
#include "http/server/request.h"
#include "model.h"
#include "model/server.h"
#include "controller/main.h"
#include "controller/inbox.h"
#include "controller/outbox.h"
#include "controller/test.h"
#include "controller/indexer.h"
#include "controller/fetch.h"
#include "tor.h"
#include "process.h"
#include <curl/curl.h>
#include <stdlib.h>
bool terminate = false;
@ -30,66 +21,6 @@ void handle_ctrl_c(int)
terminate = true;
}
void handle_request( struct http_request* req, void* )
{
//printf( "Handling request from %s\n", http_request_get_remote_host_address( req ) );
if( !route_request( req ) ) {
FILE* f = http_request_get_response_body( req );
http_request_send_headers( req, 404, "text/html", true );
#include "view/404.html.inc"
}
fflush(stdout);
}
bool run_webserver( struct app_args* args )
{
struct http_server* srv = http_server_new( args, handle_request, NULL );
if( !srv ) {
printf( "Error setting up server\n" );
app_args_release(args);
return false;
}
http_server_set_debug( srv, args->debug );
while(!terminate) {
http_server_process( srv );
usleep(25000);
}
http_server_release( srv );
return true;
}
bool run_everything( struct app_args* args )
{
// Process inbox
//*
int inbox_handler_pid = -1;
if( !( inbox_handler_pid = fork() ) ) {
prctl(PR_SET_PDEATHSIG, SIGHUP);
process_inbox();
}
//*/
//*
// Process outbox
int outbox_handler_pid = -1;
if( !( outbox_handler_pid = fork() ) ) {
prctl(PR_SET_PDEATHSIG, SIGHUP);
process_outbox();
}
//*/
if( !run_webserver(args) ) { return false; }
return true;
}
void develop();
int main( int argc, char* argv[] )
{
curl_global_init(CURL_GLOBAL_DEFAULT);
@ -103,19 +34,20 @@ int main( int argc, char* argv[] )
}
int code = 0;
printf( "section = %d\n", g_server->section );
fflush(stdout);
switch(g_server->section) {
case 0: code = !run_webserver(g_server); break;
case 1: process_inbox(); break;
case 2: process_outbox(); break;
case 3: built_in_test(); break;
case 4: reindex(); break;
case 5: process_fetch(); break;
case 6: start_tor(); break;
case 100: develop(); break;
default: code = !run_everything(g_server); break;
if( g_server->section == -1 ) {
printf( "Starting Apogee ActivityPub server...\n" );
process_start_section(6);
sleep(3);
process_start_section(0);
process_start_section(1);
process_start_section(2);
process_start_section(5);
process_wait_for_finished();
printf( "Apogee server shutting down...\n" );
code = EXIT_SUCCESS;
} else {
printf( "section = %d\n", g_server->section );
process_run_section( g_server->section );
}
curl_global_cleanup();

@ -1,13 +1,160 @@
#include "process.h"
#include "model/server.h"
#include "controller/main.h"
#include "controller/inbox.h"
#include "controller/outbox.h"
#include "controller/test.h"
#include "controller/indexer.h"
#include "controller/fetch.h"
#include "tor.h"
#include "collections/array.h"
#include "http/server/server.h"
#include "http/server/request.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
struct process
{
int pid;
pid_t pid;
int section;
};
struct {
struct process** items;
int count;
} process_list;
extern bool terminate;
static void handle_request( struct http_request* req, void* )
{
//printf( "Handling request from %s\n", http_request_get_remote_host_address( req ) );
if( !route_request( req ) ) {
FILE* f = http_request_get_response_body( req );
http_request_send_headers( req, 404, "text/html", true );
#include "view/404.html.inc"
}
fflush(stdout);
}
static bool run_webserver( struct app_args* args )
{
struct http_server* srv = http_server_new( args, handle_request, NULL );
if( !srv ) {
printf( "Error setting up server\n" );
return false;
}
http_server_set_debug( srv, args->debug );
while(!terminate) {
http_server_process( srv );
usleep(25000);
}
http_server_release( srv );
return true;
}
void develop();
int process_run_section( int id )
{
printf( "Starting section %d\n", id );
switch( id ) {
case 0:
return !run_webserver( g_server );
case 1:
process_inbox();
return EXIT_SUCCESS;
case 2:
process_outbox();
return EXIT_SUCCESS;
case 3:
built_in_test();
return EXIT_SUCCESS;
case 4:
reindex();
return EXIT_SUCCESS;
case 5:
process_fetch();
return EXIT_SUCCESS;
case 6:
start_tor();
return EXIT_SUCCESS;
case 100:
develop();
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
static void redirect_io( int section )
{
const char* filename = NULL;
switch( section ) {
case 0: filename = "data/logs/webserver.log"; break;
case 1: filename = "data/logs/inbox.log"; break;
case 2: filename = "data/logs/outbox.log"; break;
case 5: filename = "data/logs/fetch.log"; break;
case 6: filename = "data/logs/tor.log"; break;
}
if( !filename ) { return; }
int log = open( filename, O_CREAT | O_RDWR | O_APPEND, 0644 );
if( !log ) {
printf( "Unable to redirect I/O to log file %s: %s\n", filename, strerror(errno) );
return;
}
dup2( log, 1 );
dup2( log, 2 );
close( log );
}
void process_start_section( int id )
{
printf( "Starting section %d\n", id );
pid_t child_pid;
child_pid = fork();
if( child_pid ) {
// Parent
if( child_pid == -1 ) {
printf( "Failed to fork child process\n" );
return;
}
struct process* child;
child = malloc(sizeof(*child));
memset(child,0,sizeof(*child));
child->pid = child_pid;
child->section = id;
array_append( &process_list, sizeof(child), &child );
} else {
redirect_io( id );
// Child
exit( process_run_section(id) );
}
}
void process_stop()
@ -16,5 +163,28 @@ void process_stop()
void process_wait_for_finished()
{
while( !terminate ) {
usleep(100000); // sleep for 100ms
for( int i = 0; i < process_list.count; ++i ) {
struct process* child = process_list.items[i];
int status;
pid_t result = waitpid( child->pid, &status, WNOHANG );
if( result == child->pid ) {
int section = child->section;
printf( "Child process %d exited\n", child->pid );
array_delete( &process_list, sizeof(child), &child );
i -= 1;
if( !terminate ) {
// TODO: restart child process
printf( "Restarting...\n" );
process_start_section( section );
}
}
}
}
}

@ -1,5 +1,6 @@
#pragma once
int process_run_section( int id );
void process_start_section( int id );
void process_stop();
void process_wait_for_finished();

@ -15,12 +15,6 @@ int start_tor()
return 1;
}
// Replace stdout and stderr with log file
int log = open( "data/logs/tor.log", O_CREAT | O_RDWR | O_SYNC, 0644 );
dup2( log, 1 );
dup2( log, 2 );
close(log);
mkdir( "data/tor", 0755 );
chdir( "data/tor" );

Loading…
Cancel
Save