Edgewall Software

Ticket #8507: trac.wsgi

File trac.wsgi, 3.7 KB (added by Shane Caraveo <shanec@…>, 8 years ago)

trac.wsgi

Line 
1#!/data/trac/bin/python
2# -*- coding: utf-8 -*-
3
4# optional dependencies include
5# line_profiler: http://packages.python.org/line_profiler/
6# line based per-function profiler for python
7#
8# psutil: http://code.google.com/p/psutil/
9# cross platform cpu and memory measurements
10#
11# lsprofcalltree: http://codespeak.net/pypy/dist/pypy/tool/lsprofcalltree.py
12# prof to cachegrind conversion
13
14# a good chunk of logic borrowed from kernprof, now part of the
15# line_profiler module
16DEFAULT_ENV='/data/trac/environment'
17import os, sys, time
18
19def preload():
20 global DEFAULT_ENV
21 # open the master repository to preload a trac instance and plugins
22 # using wsgi 3.0, we can import this script prior to a request and
23 # get much of trac loaded.
24 from trac.env import open_environment
25 env = open_environment(DEFAULT_ENV, use_cache=True)
26 env.shutdown()
27#preload()
28
29# if gc.collect is disabled in trac.web.main, this thread handles a heartbeat
30# that will gc.collect every few seconds, rather than every request.
31import threading, gc
32class GcCollect():
33 def __init__(self):
34 self._shutdown = False
35 self._cv = threading.Condition()
36 self._thread = threading.Thread(target = GcCollect._collect,
37 name = "Trac GcCollect",
38 args = (self,))
39 self._thread.start()
40
41 def __del__(self):
42 self.shutdown()
43
44 def shutdown(self):
45 self._shutdown = True
46 if self._thread.isAlive():
47 self._cv.acquire()
48 self._cv.notify()
49 self._cv.release()
50
51 def _collect(self):
52 print >> sys.stderr, "GcCollect started"
53 while not self._shutdown:
54 self._cv.acquire()
55 try:
56 self._cv.wait(10)
57 finally:
58 self._cv.release()
59 gc.collect()
60 print >> sys.stderr, "GcCollect stopped"
61collector = None
62
63def the_application(environ, start_request):
64 if not 'trac.env_path_parent_dir' in environ:
65 global DEFAULT_ENV
66 environ.setdefault('trac.env_path', DEFAULT_ENV)
67 if 'PYTHON_EGG_CACHE' in environ:
68 os.environ['PYTHON_EGG_CACHE'] = environ['PYTHON_EGG_CACHE']
69 elif 'trac.env_path' in environ:
70 os.environ['PYTHON_EGG_CACHE'] = os.path.join(environ['trac.env_path'],
71 '.egg-cache')
72 elif 'trac.env_path_parent_dir' in environ:
73 os.environ['PYTHON_EGG_CACHE'] = os.path.join(environ['trac.env_path_parent_dir'],
74 '.egg-cache')
75 from trac.web.main import dispatch_request
76 return dispatch_request(environ, start_request)
77
78# avoid having to remove all @profile decorators if you want to do
79# a quick change to call profiling, if tracdev gets loaded it will
80# overwrite this
81import __builtin__
82__builtin__.__dict__['profile'] = lambda a: a
83
84def application(environ, start_request):
85 global collector
86 if collector is None:
87 if environ.get('trac.gccollect', False):
88 collector = GcCollect()
89 else:
90 collector = False
91 if int(environ.get('trac.profile_enabled', '0')):
92 from tracdev import ProfileHandler
93 return ProfilerHandler(the_application, environ, start_request)()
94 elif int(environ.get('dbgp.enabled', '0')):
95 from tracdev import DBGPHandler
96 return DBGPHandler(the_application, environ, start_request)()
97 #else:
98 # toss an exception if the cpu usage gets high, primarily a tool
99 # to verify where cpu is getting used
100 # from tracdev import cpu_time_exception
101 # cpu = cpu_time_exception()
102 return the_application(environ, start_request)