User Tools

Site Tools


programming:python:py-prefork-server

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
programming:python:py-prefork-server [2012/09/05 16:53] – [Hooks] jayprogramming:python:py-prefork-server [2023/11/10 20:06] (current) – [Donations] jay
Line 21: Line 21:
 **NOTE:** The RPMs are **not** guaranteed to be the latest versions.  Check [[https://github.com/crustymonkey/py-prefork-server|Github]] to find out what the latest version is.  That said, I will try and keep these up to date. **NOTE:** The RPMs are **not** guaranteed to be the latest versions.  Check [[https://github.com/crustymonkey/py-prefork-server|Github]] to find out what the latest version is.  That said, I will try and keep these up to date.
  
-{{:programming:python:py-prefork-server-0.1.2-1.noarch.rpm|py-prefork-server-0.1.2-1.noarch.rpm}} \\ +{{:programming:python:py-prefork-server-0.1.2-1.noarch.rpm|py-prefork-server-0.4.0-1.noarch.rpm}} \\ 
-{{:programming:python:py-prefork-server-0.1.2-1.src.rpm|py-prefork-server-0.1.2-1.src.rpm}} +{{:programming:python:py-prefork-server-0.1.2-1.src.rpm|py-prefork-server-0.4.0-1.src.rpm}}
-===== Donations ===== +
-By no means should anyone feel they //have// to donate.  However, if you've used this stuff to save some time, prevent head shaped holes in the wall, raise your children or you just think this is awesome and want to contribute to my [[http://www.surlybrewing.com/|Surly]] fund (that stuff isn't cheap, but it's soooooo good), you can click the [[http://paypal.com|Paypal]] donate button below and toss me a couple of dollars.  I've heard from others who have donated that they were visited by flying monkeys that spoke Icelandic, and were subsequently showered with fantastic gifts from said monkeys.  I don't know if this is true, or if drug use was involved, but it still sounds pretty awesome.+
  
-<html> 
-<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> 
-<input type="hidden" name="cmd" value="_s-xclick"> 
-<input type="hidden" name="hosted_button_id" value="83ENX2ZV8E694"> 
-<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> 
-<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> 
-</form> 
-</html> 
 ===== Issues and Feature Requests ===== ===== Issues and Feature Requests =====
-Please use the bug tracker built in to [[http://github.com|Github]] for all bug reports and feature requests+Please use the bug tracker built in to [[https://github.com/crustymonkey/py-prefork-server|Github]] for all bug reports and feature requests
  
 ===== Code Contributions ===== ===== Code Contributions =====
-I'm always open to code contributions.  Please use the "fork" and "pull request" mechanisms on [[http://github.com|Github]] for this.+I'm always open to code contributions.  Please use the "fork" and "pull request" mechanisms on [[https://github.com/crustymonkey/py-prefork-server|Github]] for this.
 ===== Installing ===== ===== Installing =====
 To manually install the package: To manually install the package:
Line 68: Line 58:
  
 class MyChild(preforkserver.BaseChild): class MyChild(preforkserver.BaseChild):
-    def processRequest(self):+    def process_request(self):
         # handle the connection here         # handle the connection here
 </code> </code>
-One important thing to remember is that any instance variables that are set here will have to be done so with the idea that each instance will handle a number of connections (by default, as you can set by the maxRequests argument when creating a Manager instance).  This will be discussed later.+One important thing to remember is that any instance variables that are set here will have to be done so with the idea that each instance will handle a number of connections (by default, as you can set by the max_requests argument when creating a Manager instance).  This will be discussed later.
  
 === Instance Variables === === Instance Variables ===
Line 77: Line 67:
  
 ^ Name ^ Type ^ Description ^ ^ Name ^ Type ^ Description ^
-| self.proto | str | This will be either "tcp" or "udp"+| self.protocol | str | This will be either "tcp" or "udp"
-| self.reqsHandled | int | This is the number of requests this child has handled |+| self.requests_handled | int | This is the number of requests this child has handled |
 | self.conn | socket object or str | The socket object if this is a tcp server, otherwise this will be the actual payload of the udp packet | | self.conn | socket object or str | The socket object if this is a tcp server, otherwise this will be the actual payload of the udp packet |
-| self.addr | tuple(str , int) | An address tuple containing (ip , port) |+| self.address | tuple(str , int) | An address tuple containing (ip , port) |
 | self.closed | boolean | A boolean, mainly for internal use, which says whether this child has been set to be closed | | self.closed | boolean | A boolean, mainly for internal use, which says whether this child has been set to be closed |
 | self.error | str | A string error message, if set | | self.error | str | A string error message, if set |
Line 86: Line 76:
 === Hooks === === Hooks ===
 == initialize(self) == == initialize(self) ==
-Rather than reimplementing __init__, which you can do instead, you can just override this and setup variables and such that you need to set up.  This is the recommended approach.  Note that this is only called once, when the class is initialized.  This is **NOT** called on each new connection.  Use ''postAccept()'' for that purpose.+Rather than reimplementing __init__, which you can do instead, you can just override this and setup variables and such that you need to set up.  This is the recommended approach.  Note that this is only called once, when the class is initialized.  This is **NOT** called on each new connection.  Use ''post_accept()'' for that purpose.
  
-== postAccept(self) == +== pre_bind(self) == 
-''self.conn'' and ''self.addr'' are set before this is calledas a new connection has been established.  You can make any modifications/setup before ''processRequest()'' is called.+This hook is called before the main socket is created and bound to the ip:port This is similar to the ''initialize()'' hook in the child class You can use this to set up global variablesetc.  Note that this will **only** be called if you are using reuse_port as the socket will be bound in the child process.
  
-== allowDeny(self) == +== post_bind(self) == 
-You can use this hook to refuse the connection based on the ''self.conn'' and ''self.addr'' variables that have been set.  Return ''True'' (default) here to accept the connection and ''False'' to deny it and close the connection.  This is especially useful for IP based filtering.  See ''requestDenied()'' for sending messages back to the client before the socket is closed.  Note that this is the only hook where your return value matters.+As you might have guessed, this is called right after the ''accept()'' socket has been created and bound.  Note that this will **only** be called if you are using reuse_port as the socket will be bound in the child process.
  
-== requestDenied(self) == +== post_accept(self) == 
-If you deny the connection in allowDeny()you can send message using this callback before the connection is closed.+''self.conn'' and ''self.address'' are set before this is calledas new connection has been established.  You can make any modifications/setup before ''process_request()'' is called.
  
-== processRequest(self) ==+== allow_deny(self) == 
 +You can use this hook to refuse the connection based on the ''self.conn'' and ''self.address'' variables that have been set.  Return ''True'' (default) here to accept the connection and ''False'' to deny it and close the connection.  This is especially useful for IP based filtering.  See ''request_denied()'' for sending messages back to the client before the socket is closed.  Note that this is the only hook where your return value matters. 
 + 
 +== request_denied(self) == 
 +If you deny the connection in allow_deny(), you can send a message using this callback before the connection is closed. 
 + 
 +== process_request(self) ==
 This is where you are processing the actual request.  You should use your self.conn socket to send and receive data from your client in this hook. This is where you are processing the actual request.  You should use your self.conn socket to send and receive data from your client in this hook.
  
-Remember, if this is a udp server, self.conn will be a string with the actual packet payload.  If you have a udp server, and you wish to respond, you can create a new udp connection back to the sender.+Remember, if this is a udp server, self.conn will be a string with the actual packet payload.  If you have a udp server, and you wish to respond, you can use the resp_to() method built into BaseChild.  It accepts the message responds to the current udp client. 
 + 
 +<code python> 
 +def process_request(self): 
 +    data = self.conn 
 +    self.resp_to('Received data: %s\n' % data) 
 +</code>
  
-== postProcessRequest(self) ==+== post_process_request(self) ==
 This is called after the connection is closed.  You can perform any maintenance/cleanup or post connection processing here. This is called after the connection is closed.  You can perform any maintenance/cleanup or post connection processing here.
  
Line 117: Line 119:
 === The __init__ Signature === === The __init__ Signature ===
 <code python> <code python>
-def __init__(self , childClass maxServers=20 , minServers=5 , +def __init__(self , child_class max_servers=20 , min_servers=5 , 
-        minSpareServers=2 , maxSpareServers=10 , maxRequests=0 , +        min_spare_servers=2 , max_spare_servers=10 , max_requests=0 , 
-        bindIp='127.0.0.1' , port=10000 , proto='tcp' , listen=5):+        bind_ip='127.0.0.1' , port=10000 , protocol='tcp' , listen=5 
 +        reuse_port=False):
 </code> </code>
 Here is short description of each of those variables. Here is short description of each of those variables.
 ^ Name ^ Type ^ Description ^ ^ Name ^ Type ^ Description ^
-childClass | BaseChild | An implentation of BaseChild to define the child processes | +child_class | BaseChild | An implentation of BaseChild to define the child processes | 
-maxServers | int | Maximum number of children that can exist at any time | +max_cervers | int | Maximum number of children that can exist at any time | 
-minServers | int | Minimum number of children to have | +min_servers | int | Minimum number of children to have | 
-minSpareServers | int | Minimum number of spare children to have | +min_spare_servers | int | Minimum number of spare children to have | 
-maxSpareServers | int | Maximum number of spare children to have | +max_spare_servers | int | Maximum number of spare children to have | 
-maxRequests | int | Maximum number of requests each child should handle.  Zero is unlimited and the default. | +max_requests | int | Maximum number of requests each child should handle.  Zero is unlimited and the default. | 
-bindIp | str | The IP address to bind to |+bind_ip | str | The IP address to bind to |
 | port | int | The port number to bind to | | port | int | The port number to bind to |
-proto | str | The protocol to use (tcp or udp) |+protocol | str | The protocol to use (tcp or udp) |
 | listen | int | TCP listen queue backlog | | listen | int | TCP listen queue backlog |
 +| reuse_port | bool | If set, and available, SO_REUSEPORT will be used to bind the socket in the child |
 For anyone who has set up an Apache prefork server (or used Perl's ''Net::Server::PreFork''), this should look pretty familiar. For anyone who has set up an Apache prefork server (or used Perl's ''Net::Server::PreFork''), this should look pretty familiar.
  
Line 140: Line 144:
 Here they are with a brief description. Here they are with a brief description.
  
-== preBind(self) == +== pre_bind(self) == 
-This hook is called before the main socket is created and bound to the ip:port.  This is similar to the ''initialize()'' hook in the child class.  You can use this to set up global variables, etc.+This hook is called before the main socket is created and bound to the ip:port.  This is similar to the ''initialize()'' hook in the child class.  You can use this to set up global variables, etc.  Note that this will **not** be called if you are using reuse_port as the socket will be bound in the child process.
  
-== postBind(self) == +== post_bind(self) == 
-As you might have guessed, this is called right after the ''accept()'' socket has been created and bound.+As you might have guessed, this is called right after the ''accept()'' socket has been created and bound.  Note that this will **not** be called if you are using reuse_port as the socket will be bound in the child process.
  
-== preSignalSetup(self) ==+== pre_signal_setup(self) ==
 This is called before the signal handlers are set up This is called before the signal handlers are set up
  
-== postSignalSetup(self) ==+== post_signal_setup(self) ==
 This is called after the signal handlers have been set.  You can override the default signal handlers if you like.  More on that below. This is called after the signal handlers have been set.  You can override the default signal handlers if you like.  More on that below.
  
-== preInitChildren(self) ==+== pre_init_children(self) ==
 This is called before the child processes are initialized. This is called before the child processes are initialized.
  
-== postInitChildren(self) ==+== post_init_children(self) ==
 This is called after the child processes are initialized. This is called after the child processes are initialized.
  
-== preLoop(self) ==+== pre_loop(self) ==
 This is the last hook before the main server loop takes over. Any last minute setup items you wish to do should be done here. This is the last hook before the main server loop takes over. Any last minute setup items you wish to do should be done here.
  
-== preServerClose(self) ==+== pre_server_close(self) ==
 This is called before the server shuts down.  Any cleanup you wish to take care of before termination should be done here. This is called before the server shuts down.  Any cleanup you wish to take care of before termination should be done here.
  
-== hupHandler(self , frame , num) ==+== hup_handler(self , frame , num) ==
 This handles a SIGHUP.  If you have a config for your server, you could reload that here.  By default, this just ignores the signal. This handles a SIGHUP.  If you have a config for your server, you could reload that here.  By default, this just ignores the signal.
  
-== intHandler(self , frame , num) ==+== int_handler(self , frame , num) ==
 This handles a SIGINT.  The default is set an internal "stop" event to gracefully shutdown.  If you override this, call the ''super()'' so the graceful shutdown happens. This handles a SIGINT.  The default is set an internal "stop" event to gracefully shutdown.  If you override this, call the ''super()'' so the graceful shutdown happens.
  
-== termHandler(self , frame , num) ==+== term_handler(self , frame , num) ==
 By default, this does exactly the same thing as ''intHandler'' with a SIGTERM. By default, this does exactly the same thing as ''intHandler'' with a SIGTERM.
  
 ===== Example ===== ===== Example =====
 There is a full, working example in the distributions ''examples'' directory. There is a full, working example in the distributions ''examples'' directory.
programming/python/py-prefork-server.1346863996.txt.gz · Last modified: 2012/09/05 16:53 by jay