Skip to content

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
houspi committed Aug 2, 2018
1 parent b739498 commit 45724c3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# PythonDaemon

Python prefork TCP server

fcgi-pm.py - TCP Server
hello.py - external program for the fcgi-pm.py

Example
./fcgi-pm.py --count=4 --queue-size=100 --cgi="/home/www/fcgi/hello.py --param1=value1 --param2=value2" --daemon=Yes
run <--count> workers, each worker process <--queue-size> requests and dies.
Server restarts each died worker.

Test with ab
ab -c 5 -n 150 http://127.0.0.1:8888/
55 changes: 47 additions & 8 deletions fcgi-pm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
#!/usr/bin/python
#
# fcgi-pm.py
# By houspi@gmail.com
#
# Python daemon
# prefork TCP server
# This is the base script
# It doesn't provide any error and exception check
# Read data from client until get double \r\n (empty line)
# Run external program
# Send output to client
#
# usage: fcgi-pm.py [-h] [--socket SOCKET] [--queue-size QUEUE_SIZE]
# [--count COUNT] [--daemon DAEMON] --cgi CGI
#
# optional arguments:
# -h, --help show this help message and exit
# --socket SOCKET host:port
# --queue-size QUEUE_SIZE Max requests per child
# --count COUNT Num of workers
# --cgi CGI Path to exucatable cgi with parameters
# --daemon DAEMON Run as a daemon. Yes/No
#

import os
import sys
Expand All @@ -12,7 +33,7 @@
import logging
import argparse

PID_FILE = '/var/run/fcgi-pm.pid'
PID_FILE = '/var/run/fcgi-pm.pid'
RUNNING_DIR = '/tmp'
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 8888
Expand All @@ -34,15 +55,21 @@ def __init__(self, pipe, pid, queue_size):


# Connection handler
# sock - Socket
# cgi_script - external script name
def handle_connection(sock, cgi_script):
logger.info('Start to process request')

# Read data from socket until double \r\n
get_data = ''
while not get_data.endswith('\r\n\r\n'):
get_data += sock.recv(BUFFER_SIZE)


# Start external program
proc = subprocess.Popen(cgi_script, shell=True, stdout=subprocess.PIPE)
(stdout_data, stderr_data) = proc.communicate()

# We mean that the program always runs successfully
status = "200 OK"
content_type = "text/plain"
send_data = '';
Expand All @@ -58,18 +85,23 @@ def handle_connection(sock, cgi_script):


# Start child process
# sock - Socket
# queue_size - max requests per child
# cgi_script - external script name
def start_child(sock, queue_size, cgi_script):
child_pipe, parent_pipe = socket.socketpair()
pid = os.fork()
# child process
if pid == 0:
# child process
child_pipe.close()
while 1:
# Read data from parent
# read data from parent
command = parent_pipe.recv(BUFFER_SIZE)
connection, (client_ip, clinet_port) = sock.accept()
logger.info('Child %d Accept connection %s:%d' % (os.getpid(), client_ip, clinet_port))
# Send answer to parent

# send answer to parent
# run external program
parent_pipe.send('accept')
handle_connection(connection, cgi_script)
connection.close()
Expand All @@ -82,18 +114,25 @@ def start_child(sock, queue_size, cgi_script):


# Main server loop
# server_host - server host
# server_port - port
# queue_size - max requests per child
# workers_count - num of workers
# cgi_script - external script name
def server_loop(server_host, server_port, queue_size, workers_count, cgi_script):
# Create new socket with flag SO_REUSEADDR
# Create new socket
# bind them and listen
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server_host, server_port))
sock.listen(DEFAULT_BACKLOG)
logger.info('Listning on %s:%d...' % (server_host, server_port))


# start workers
for i in range(workers_count):
start_child(sock, queue_size, cgi_script)


# main infinite loop
to_read = [sock] + [child.pipe.fileno() for child in childs_list.values()]
while 1:
# Test if socket is readable
Expand Down

0 comments on commit 45724c3

Please sign in to comment.