0
@@ -54,11 +54,23 @@ explicitly define some special types:
0
inactive_apps. This iterator is only valid if this AppContainer really is
0
+ Spawns a new instance of the application at the given application root.
0
+ Throws an exception if something went wrong. This function is thread-safe.
0
+ Note that application initialization can take an arbitrary amount of time.
0
The algorithm requires the following instance variables for storing state
0
+ This lock is used for implementing thread-safetiness. We assume that it
0
+ is non-recursive, i.e. if a thread locks a mutex that it has already locked,
0
+ then it will result in a deadlock.
0
- apps: map[string => list<AppContainer>]
0
Maps an application root to a list of AppContainers. Thus, this map contains
0
all application instances that are in the pool.
0
@@ -107,10 +119,6 @@ information:
0
== Algorithm in pseudo code
0
# Thread-safetiness notes:
0
-# - The following functions are to be run inside the same lock:
0
-# * session_has_been_closed()
0
-# * The cleaner thread's main function.
0
# - All wait commands are to unlock the lock during waiting.
0
function get(app_root):
0
@@ -118,23 +126,24 @@ function get(app_root):
0
- container, list = spawn_or_use_existing(app_root)
0
- container.last_used = current_time()
0
- return container.app.connect()
0
- if (attempt == MAX_ATTEMPTS):
0
- # The app instance seems to have crashed. So we remove this
0
- # instance from our data structures.
0
- list.remove(container.iterator)
0
+ container, list = spawn_or_use_existing(app_root)
0
+ container.last_used = current_time()
0
+ return container.app.connect()
0
+ if (attempt == MAX_ATTEMPTS):
0
+ # The app instance seems to have crashed. So we remove this
0
+ # instance from our data structures.
0
+ list.remove(container.iterator)
0
# Returns a pair of [AppContainer, list<AppContainer>] that matches the
0
@@ -207,7 +216,7 @@ function spawn_or_use_existing(app_root):
0
container = new AppContainer
0
# TODO: we should unlock the mutex during spawning,
0
# and add some kind of timeout check.
0
- container.app = spawn(app
)
0
+ container.app = spawn(app
_root)
0
container.sessions = 0;
0
@@ -224,14 +233,15 @@ function spawn_or_use_existing(app_root):
0
# _container_ is the AppContainer that contains the application for which a
0
# session has been closed.
0
function session_has_been_closed(container):
0
- list = apps[container.app.app_root]
0
- container.last_used = current_time()
0
- if container.sessions == 0:
0
- list.move_to_front(container.iterator)
0
- container.ia_iterator = inactive_apps.add_to_back(container.app)
0
+ list = apps[container.app.app_root]
0
+ container.last_used = current_time()
0
+ if container.sessions == 0:
0
+ list.move_to_front(container.iterator)
0
+ container.ia_iterator = inactive_apps.add_to_back(container.app)
0
function needs_restart(app_root):
0
@@ -258,22 +268,23 @@ function needs_restart(app_root):
0
# The following thread will be responsible for cleaning up idle application
0
# instances, i.e. instances that haven't been used for a while.
0
- Wait until CLEAN_INTERVAL seconds have expired, or until the thread has been signalled to quit.
0
- if thread has been signalled to quit:
0
+ Wait until CLEAN_INTERVAL seconds have expired, or until the thread has been signalled to quit.
0
+ if thread has been signalled to quit:
0
- for all container in inactive_apps:
0
- app_list = apps[app.app_root]
0
- if now - container.last_used > MAX_IDLE_TIME:
0
- app_list.remove(container.iterator)
0
- inactive_apps.remove(iterator for container)
0
- apps.remove(app.app_root)
0
- restart_file_times.remove(app.app_root)
0
+ for all container in inactive_apps:
0
+ app_list = apps[app.app_root]
0
+ if now - container.last_used > MAX_IDLE_TIME:
0
+ app_list.remove(container.iterator)
0
+ inactive_apps.remove(iterator for container)
0
+ apps.remove(app.app_root)
0
+ restart_file_times.remove(app.app_root)
Comments
No one has commented yet.