File: //opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyo
�
a�Nc           @   s  d  Z  d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l	 m
 Z
 d d l m Z m
 Z
 d d l m Z m Z e d d	 d
 �Z d e f d �  �  YZ d
 �  Z d g Z d �  Z d �  Z d �  Z e d � Z e j  e _  d d � Z d S(   sv   
Watches the key ``paste.httpserver.thread_pool`` to see how many
threads there are and report on any wedged threads.
i����N(   t   StringIO(   t	   get_ident(   t   httpexceptions(   t
   construct_urlt   parse_formvars(   t   HTMLTemplatet   bunchsv  
<html>
 <head>
  <style type="text/css">
   body {
     font-family: sans-serif;
   }
   table.environ tr td {
     border-bottom: #bbb 1px solid;
   }
   table.environ tr td.bottom {
     border-bottom: none;
   }
   table.thread {
     border: 1px solid #000;
     margin-bottom: 1em;
   }
   table.thread tr td {
     border-bottom: #999 1px solid;
     padding-right: 1em;
   }
   table.thread tr td.bottom {
     border-bottom: none;
   }
   table.thread tr.this_thread td {
     background-color: #006;
     color: #fff;
   }
   a.button {
     background-color: #ddd;
     border: #aaa outset 2px;
     text-decoration: none;
     margin-top: 10px;
     font-size: 80%;
     color: #000;
   }
   a.button:hover {
     background-color: #eee;
     border: #bbb outset 2px;
   }
   a.button:active {
     border: #bbb inset 2px;
   }
  </style>
  <title>{{title}}</title>
 </head>
 <body>
  <h1>{{title}}</h1>
  {{if kill_thread_id}}
  <div style="background-color: #060; color: #fff;
              border: 2px solid #000;">
  Thread {{kill_thread_id}} killed
  </div>
  {{endif}}
  <div>Pool size: {{nworkers}}
       {{if actual_workers > nworkers}}
         + {{actual_workers-nworkers}} extra
       {{endif}}
       ({{nworkers_used}} used including current request)<br>
       idle: {{len(track_threads["idle"])}},
       busy: {{len(track_threads["busy"])}},
       hung: {{len(track_threads["hung"])}},
       dying: {{len(track_threads["dying"])}},
       zombie: {{len(track_threads["zombie"])}}</div>
{{for thread in threads}}
<table class="thread">
 <tr {{if thread.thread_id == this_thread_id}}class="this_thread"{{endif}}>
  <td>
   <b>Thread</b>
   {{if thread.thread_id == this_thread_id}}
   (<i>this</i> request)
   {{endif}}</td>
  <td>
   <b>{{thread.thread_id}}
    {{if allow_kill}}
    <form action="{{script_name}}/kill" method="POST"
          style="display: inline">
      <input type="hidden" name="thread_id" value="{{thread.thread_id}}">
      <input type="submit" value="kill">
    </form>
    {{endif}}
   </b>
  </td>
 </tr>
 <tr>
  <td>Time processing request</td>
  <td>{{thread.time_html|html}}</td>
 </tr>
 <tr>
  <td>URI</td>
  <td>{{if thread.uri == 'unknown'}}
      unknown
      {{else}}<a href="{{thread.uri}}">{{thread.uri_short}}</a>
      {{endif}}
  </td>
 <tr>
  <td colspan="2" class="bottom">
   <a href="#" class="button" style="width: 9em; display: block"
      onclick="
        var el = document.getElementById('environ-{{thread.thread_id}}');
        if (el.style.display) {
            el.style.display = '';
            this.innerHTML = '▾ Hide environ';
        } else {
            el.style.display = 'none';
            this.innerHTML = '▸ Show environ';
        }
        return false
      ">▸ Show environ</a>
   
   <div id="environ-{{thread.thread_id}}" style="display: none">
    {{if thread.environ:}}
    <table class="environ">
     {{for loop, item in looper(sorted(thread.environ.items()))}}
     {{py:key, value=item}}
     <tr>
      <td {{if loop.last}}class="bottom"{{endif}}>{{key}}</td>
      <td {{if loop.last}}class="bottom"{{endif}}>{{value}}</td>
     </tr>
     {{endfor}}
    </table>
    {{else}}
    Thread is in process of starting
    {{endif}}
   </div>
   {{if thread.traceback}}
   <a href="#" class="button" style="width: 9em; display: block"
      onclick="
        var el = document.getElementById('traceback-{{thread.thread_id}}');
        if (el.style.display) {
            el.style.display = '';
            this.innerHTML = '▾ Hide traceback';
        } else {
            el.style.display = 'none';
            this.innerHTML = '▸ Show traceback';
        }
        return false
      ">▸ Show traceback</a>
    <div id="traceback-{{thread.thread_id}}" style="display: none">
      <pre class="traceback">{{thread.traceback}}</pre>
    </div>
    {{endif}}
  </td>
 </tr>
</table>
{{endfor}}
 </body>
</html>
t   names   watchthreads.page_templatet   WatchThreadsc           B   s5   e  Z d  Z e d � Z d �  Z d �  Z d �  Z RS(   si  
    Application that watches the threads in ``paste.httpserver``,
    showing the length each thread has been working on a request.
    If allow_kill is true, then you can kill errant threads through
    this application.
    This application can expose private information (specifically in
    the environment, like cookies), so it should be protected.
    c         C   s
   | |  _  d  S(   N(   t
   allow_kill(   t   selfR	   (    (    sI   /opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyt   __init__�   s    c         C   s\   d | k r# | d d g � d g S| j  d � d k rH |  j | | � S|  j | | � Sd  S(	   Ns   paste.httpserver.thread_pools
   403 Forbiddens   Content-types
   text/plainsC   You must use the threaded Paste HTTP server to use this applicationt	   PATH_INFOs   /kill(   s   Content-types
   text/plain(   t   gett   killt   show(   R
   t   environt   start_response(    (    sI   /opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyt   __call__�   s    c         C   s�  | d d g � t  | � } | j d � r8 | d } n d  } | d } | j } t j �  } | j j �  } | j d d �  � g  }	 x� | D]� \ }
 \ } } t �  }
 |	 j	 |
 � | r� t
 | � |
 _ n	 d |
 _ |
 |
 _ t
 | | � |
 _ t |
 j � |
 _ | |
 _ t |
 � |
 _ q� Wt j d	 d
 d | d t | j � d
 t | � d | d d | d |  j d |	 d t �  d | j �  � 
} | g S(   Ns   200 OKs   Content-types	   text/htmlR   s   paste.httpserver.thread_poolt   keyc         S   s   |  d d S(   Ni   i    (    (   t   v(    (    sI   /opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyt   <lambda>�   s    t   unknownt   titles   Thread Pool Worker Trackert   nworkerst   actual_workerst
   nworkers_usedt   script_namet   SCRIPT_NAMEt   kill_thread_idR	   t   threadst   this_thread_idt
   track_threads(   s   Content-types	   text/html(   R   R
   t   NoneR   t   timet   worker_trackert   itemst   sortR   t   appendR   t   urit	   thread_idt   format_timet	   time_htmlt   shortent	   uri_shortR   t   traceback_threadt	   tracebackt
   page_templatet
   substitutet   lent   workersR	   R   R    (   R
   R   R   t   formR   t   thread_poolR   t   nowR2   R   R(   t   time_startedt   worker_environt   threadt   page(    (    sI   /opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyR   �   sD    
		
				
		c         C   s�   |  j  s% t j d � } | | | � St | � } t | d � } | d } | | j k rz t j d | � } | | | � S| j | � | d p� d } t j d d | d	 | f g � } | | | � S(
   Ns?   Killing threads has not been enabled.  Shame on you for trying!R(   s   paste.httpserver.thread_poolsB   You tried to kill thread %s, but it is not working on any requestsR   t   /t   headerst   Locations   ?kill=%s(	   R	   R   t
   HTTPForbiddenR   t   intR#   t   PreconditionFailedt   kill_workert	   HTTPFound(   R
   R   R   t   exct   varsR(   R4   R   (    (    sI   /opt/alt/python27/lib/python2.7/site-packages/paste/debug/watchthreads.pyR   �   s"