Commenting, adding Doxyfile, enhancing Makefile
This commit is contained in:
parent
e2dd5a1be4
commit
ebb01bb82e
6 changed files with 2656 additions and 10 deletions
16
Makefile
16
Makefile
|
|
@ -1,7 +1,17 @@
|
|||
all:
|
||||
+make -C src
|
||||
|
||||
.PHONY: clean
|
||||
doc:
|
||||
doxygen
|
||||
|
||||
clean:
|
||||
make -C src clean
|
||||
.PHONY: distclean clean __pycache__clean doc
|
||||
|
||||
distclean: __pycache__clean
|
||||
-make -C src distclean;\
|
||||
rm -Rvf doc/latex doc/html doc/man
|
||||
|
||||
clean: __pycache__clean
|
||||
-make -C src clean;\
|
||||
|
||||
__pycache__clean:
|
||||
rm -Rvf __pycache__
|
||||
|
|
|
|||
12
src/Makefile
12
src/Makefile
|
|
@ -4,18 +4,22 @@ CFLAGS=-c -Wall `python3-config --includes`
|
|||
LDFLAGS=`python3-config --libs` -lfcgi
|
||||
#LDFLAGS= -L`python3-config --configdir` `python3-config --libs` -lfcgi
|
||||
|
||||
BIN=pyfcgi
|
||||
SRCS=$(wildcard *.c)
|
||||
OBJS=$(SRCS:.c=.o)
|
||||
|
||||
all: pyfcgi
|
||||
all: $(BIN)
|
||||
|
||||
pyfcgi: $(OBJS)
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
.PHONY: clean distclean
|
||||
|
||||
distclean: clean
|
||||
-rm -v $(BIN)
|
||||
|
||||
clean:
|
||||
@rm -v $(OBJS)
|
||||
-rm -v $(OBJS)
|
||||
|
|
|
|||
74
src/main.c
74
src/main.c
|
|
@ -16,6 +16,19 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**@defgroup processes Process organisation of PyFCGI
|
||||
*
|
||||
* PyFCGI is organised in three layer :
|
||||
* A @ref main_proc : simple, that keep running and spawn a
|
||||
* @ref work_master_proc . This process handles @ref worker_process creation
|
||||
* and try to maintain a pool able to reply efficiently to CGI requests.
|
||||
*/
|
||||
/**@defgroup main_proc Main process
|
||||
* @brief The main process in the @ref main() function
|
||||
* @ingroup processes
|
||||
*/
|
||||
|
||||
#include <fcgi_stdio.h> /* fcgi library; put it first*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
|
@ -76,7 +89,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else if(!child)
|
||||
{
|
||||
responder_loop(py_entrypoint, MAX_REQS, 1, 20);
|
||||
responder_loop(py_entrypoint, MAX_REQS, 1, 30);
|
||||
exit((unsigned char)-1);
|
||||
}
|
||||
waitpid(child, &child_ret, 0);
|
||||
|
|
@ -94,3 +107,62 @@ int main(int argc, char **argv)
|
|||
closelog();
|
||||
free(ident);
|
||||
}
|
||||
|
||||
/**@mainpage PyFCGI
|
||||
* @section main_what What is PyFCGI ?
|
||||
* PyFCGI is a simple python3 fastcgi runner.
|
||||
*
|
||||
* Usage : *PY_ENTRYPOINT='foo' spawn-fcgi -d . -n src/pyfcgi -p 9000 -a 127.0.0.1*
|
||||
*
|
||||
* To run foo.entrypoint() python function.
|
||||
*
|
||||
* @subsection main_how_use How to use it ?
|
||||
*
|
||||
* @warning For the moment PyFCGI is under heavy developpement and in early
|
||||
* stage. Everything will change ;o)
|
||||
*
|
||||
* PyFCGI should be runned with spawn-fcgi (or something similar), allowing
|
||||
* to configure & forward environnement variables to libFCGI.
|
||||
*
|
||||
* For the moment no configuration files exists. You have to pass a
|
||||
* PY_ENTRYPOINT containing an importable python module containing an
|
||||
* entrypoint() (no arguments for the moment) function.
|
||||
*
|
||||
* When called this function will have to send valid CGI data to the webserver
|
||||
* using sys.stdin (the print() function for exemple) like :
|
||||
*<code>Content-type: text/html\\r\\n\\r\\nHello world !\\n</code>
|
||||
*
|
||||
* The function will have access to updated CGI os.environ containing
|
||||
* all informations about a request
|
||||
*
|
||||
* @subsubsection main_how_use_syslog Logging, using syslog
|
||||
*
|
||||
* Right now PyFCGI uses syslog() to log stuff using a pyfcgi ident.
|
||||
* PyFCGI logs can be filtered using /etc/rsyslog.d/pyfcgi.conf :
|
||||
*
|
||||
<pre>
|
||||
if ($programname contains 'pyfcgi') then {
|
||||
-/var/log/pyfcgi/pyfcgi.log
|
||||
stop
|
||||
}
|
||||
</pre>
|
||||
*
|
||||
* @subsubsection main_how_use_hardcode Hardcoded stuffs
|
||||
*
|
||||
* Right now there is a lot of hardcodd stuff. Fortunatly a vast majority
|
||||
* is in @ref main.c like the minimum and maximum number of workers, or
|
||||
* the number of requests before a worker restart. Some timers and stuff
|
||||
* are harcoded but should not in @ref pyworker.c & @ref responder.c
|
||||
*
|
||||
* @subsection main_how_works How it works ?
|
||||
*
|
||||
* - @ref processes
|
||||
* - @ref main_proc
|
||||
* - @ref work_master_proc
|
||||
* - @ref worker_process
|
||||
*
|
||||
* @subsection main_how_todo TODO
|
||||
* @todo Add another logging facility
|
||||
* @todo Add a configuration mecanism
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,44 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**@defgroup worker_process Worker processes
|
||||
* @brief Processus handling python execution with @ref work() function
|
||||
*
|
||||
* This kind of process are @ref spawn() by a @ref work_master_proc
|
||||
* @section Running Python
|
||||
* Running embed python in FCGI mean serving multiple requests with a single
|
||||
* python process, meaning :
|
||||
* - environnement variable of the living Python process need to be updated
|
||||
* - we need a way to communicate with python code
|
||||
*
|
||||
* @subsection worker_proc_ipc Communicating with python
|
||||
* sys.stdout & sys.stderr will be used to communicate in python. Shortly
|
||||
* after python initialize @ref update_python_fd() update these two file
|
||||
* objects with freshly created pipes.
|
||||
*
|
||||
* @subsubsection worker_proc_ipc_piper The piper process
|
||||
*
|
||||
* When a request arrive, the worker process fork again in a @ref worker_piper() child
|
||||
* process that will read the two pipes. Sending stdout to FCGI using printf
|
||||
* and stderr to syslog.
|
||||
*
|
||||
* @subsection worker_proc_environ Updating os.environ
|
||||
* os.environ is a special kind of dictionnary, automatically calling
|
||||
* os.putenv() function. This function will attempt (and succeed) to update
|
||||
* the real process environnement, making a nasty conflict with libfcgi (trying
|
||||
* to free an environnement it did not create anymore...).
|
||||
*
|
||||
* The os.environ is replaced by a simple python dict by @ref update_pyenv()
|
||||
* once a request.
|
||||
*
|
||||
* @see update_python_path()
|
||||
*
|
||||
* @ingroup processes
|
||||
* @ingroup work_master_proc
|
||||
*/
|
||||
/**@file pyworker.h
|
||||
* @ingroup worker_process
|
||||
*/
|
||||
#ifndef _PYWORKER__H___
|
||||
#define _PYWORKER__H___
|
||||
|
||||
|
|
@ -48,6 +86,7 @@ typedef unsigned long int pywrkid_t;
|
|||
|
||||
|
||||
/**@brief the function that initialize the python worker
|
||||
* @ingroup worker_process
|
||||
* @param char* python_entrypoint a path to a python entrypoint
|
||||
* @param int worker uid
|
||||
* @param int semid for FCGI access
|
||||
|
|
@ -58,6 +97,7 @@ int work(char*, int, int, int);
|
|||
|
||||
/**@brief function for a subprocess designed to read stdin & stdout from
|
||||
* python & forward them to syslog or FCGI
|
||||
* @ingroup worker_process
|
||||
* @param int worker id
|
||||
* @param int request id
|
||||
* @param int pystdout
|
||||
|
|
@ -87,12 +127,14 @@ void fetch_pyflush(PyObject**, PyObject**);
|
|||
void update_python_path();
|
||||
|
||||
/**@brief Create two pipes for stdout & stderr
|
||||
* @ingroup worker_process
|
||||
* @params int[2] pystdout
|
||||
* @params int[2] pystderr
|
||||
*/
|
||||
void update_python_fd(int[2], int[2]);
|
||||
|
||||
/**@brief Clear then update python sys.environ using current FCI environ
|
||||
* @ingroup worker_process
|
||||
* @note The environ has to be set without a call to os.putenv, the problem
|
||||
* is that the os.environ is a special mapping calling putenv on setitem...
|
||||
* For these reason the os.environ will be replaced by a new dict instance for
|
||||
|
|
|
|||
|
|
@ -16,6 +16,28 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**@defgroup work_master_proc Worker handler process
|
||||
* @brief This process use the @ref responder_loop() function as "main" function
|
||||
*
|
||||
* @section work_master_spawn Spawning workers
|
||||
* This subprocess handle worker spawning using @ref spawn(). A POSIX semaphore
|
||||
* allow to know when the worker pool is idle or not :
|
||||
*
|
||||
* @subsection work_master_spawn_sem Semaphore idle & busy detection
|
||||
* When a new worker is ready (idle) it add 1 to the semaphore, when processing
|
||||
* a request it substract 1 to the semaphore (done in @ref work() function in
|
||||
* @ref worker_process )
|
||||
*
|
||||
* When semtimedop blocks on wait_for_zero operation it means that the pool is
|
||||
* idle. Instead, if the semtimedop returns imediately it means a new worker
|
||||
* can be spawned.
|
||||
*
|
||||
* @ingroup processes
|
||||
* @ingroup main_proc
|
||||
*/
|
||||
/**@file responder.h
|
||||
* @ingroup work_master_proc
|
||||
*/
|
||||
#ifndef _RESPONDER__H___
|
||||
#define _RESPONDER__H___
|
||||
#include "config.h"
|
||||
|
|
@ -40,7 +62,7 @@ extern int pyfcgi_semid;
|
|||
void init_context();
|
||||
|
||||
/**@brief The responder loop
|
||||
*
|
||||
* @ingroup work_master_proc
|
||||
* The main function of the fcgi app fork child
|
||||
* @param int max_requests : exit normally after this number of requests. If
|
||||
* 0 given never exit.
|
||||
|
|
@ -55,7 +77,7 @@ int responder_loop(char *py_entrypoint, unsigned int max_reqs,
|
|||
|
||||
|
||||
/**@brief Spawn a worker given an entrypoint
|
||||
*
|
||||
* @ingroup work_master_proc
|
||||
* Spawn a new worker process and prepare ENV & request forwarding
|
||||
* @param char* python_entrypoint a path to a python entrypoint
|
||||
* @param int worker uid
|
||||
|
|
@ -66,12 +88,14 @@ int responder_loop(char *py_entrypoint, unsigned int max_reqs,
|
|||
pid_t spawn(char*, int, int, int);
|
||||
|
||||
/**@brief Generate a new semaphore from given key
|
||||
* @ingroup work_master_proc
|
||||
* @note set pyfcgi_semid
|
||||
* @return int semid
|
||||
*/
|
||||
int new_semaphore();
|
||||
|
||||
/**@brief Exit after closing all stuff like semaphores
|
||||
* @ingroup work_master_proc
|
||||
*/
|
||||
void clean_exit(int);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue