0
For efficiency reasons, Passenger keeps a pool spawned Rails/Ruby applications.
0
Please read the C++ API documentation for the ApplicationPool class for a full
0
-introduction. This document describes an algorithm for managing the pool.
0
+introduction. This document describes an algorithm for managing the pool, in a
0
The algorithm should strive to keep spawning to a minimum.
0
-TODO: check whether the algorithm has thrashing behavior.
0
@@ -61,6 +60,11 @@ explicitly define some special types:
0
containers[i + 1].app is active
0
* size (unsigned integer): The number of items in _instances_.
0
+ * max_requests (unsigned integer): The maximum number of requests that each
0
+ application instance in this domain may process. After having processed this
0
+ many requests, the application instance will be shut down.
0
+ A value of 0 indicates that there is no maximum.
0
A compound type (class) which contains an application instance, as well as
0
@@ -85,6 +89,16 @@ explicitly define some special types:
0
inactive_apps. This iterator is only valid if this AppContainer really is
0
+ A structure containing additional information, used by the application instance
0
+ A SpawnOptions has the following members:
0
+ * max_requests (unsigned integer) - The maximum number of requests that the
0
+ application instance may process. After having processed this many requests,
0
+ the application instance will be shut down. A value of 0 indicates that there
0
@@ -168,14 +182,18 @@ Here's an UML diagram in ASCII art:
0
# Thread-safetiness notes:
0
# - All wait commands are to unlock the lock during waiting.
0
-function get(app_root):
0
+# Connect to an existing application instance or to a newly spawned application instance.
0
+# 'app_root' specifies the application root folder of the application. 'options' is an
0
+# object of type 'SpawnOptions', which contains additional information which may be
0
+# relevant for spawning.
0
+function get(app_root, options):
0
time_limit = now() + 5 seconds
0
- container, domain = spawn_or_use_existing(app_root
)
0
+ container, domain = spawn_or_use_existing(app_root
, options)
0
container.last_used = current_time()
0
@@ -199,7 +217,7 @@ function get(app_root):
0
# Returns a pair of [AppContainer, Domain] that matches the given application
0
# root. If no such AppContainer exists, then it is created and a new
0
# application instance is spawned. All exceptions that occur are propagated.
0
-function spawn_or_use_existing(app_root
):
0
+function spawn_or_use_existing(app_root
, options):
0
domain = domains[app_root]
0
if (domain != nil) and (needs_restart(app_root)):
0
@@ -284,6 +302,7 @@ function spawn_or_use_existing(app_root):
0
+ domain.max_requests = options.max_requests
0
domains[app_root] = domain
0
@@ -301,13 +320,26 @@ function session_has_been_closed(container):
0
domain = domains[container.app.app_root]
0
- container.last_used = current_time()
0
+ instances = domain.instances
0
- if container.sessions == 0:
0
- domain.instances.move_to_front(container.iterator)
0
- container.ia_iterator = inactive_apps.add_to_back(container.app)
0
+ if (domain.max_requests) > 0 and (container.processed >= domain.max_requests):
0
+ # The application instance has processed its maximum allowed
0
+ # number of requests, so we shut it down.
0
+ instances.remove(container.iterator)
0
+ domains.remove(app_root)
0
+ container.last_used = current_time()
0
+ if container.sessions == 0:
0
+ instances.move_to_front(container.iterator)
0
+ container.ia_iterator = inactive_apps.add_to_back(container.app)
0
function needs_restart(app_root):
Comments
No one has commented yet.