Home | History | Annotate | Download | only in server
      1 # Copyright 2012 the V8 project authors. All rights reserved.
      2 # Redistribution and use in source and binary forms, with or without
      3 # modification, are permitted provided that the following conditions are
      4 # met:
      5 #
      6 #     * Redistributions of source code must retain the above copyright
      7 #       notice, this list of conditions and the following disclaimer.
      8 #     * Redistributions in binary form must reproduce the above
      9 #       copyright notice, this list of conditions and the following
     10 #       disclaimer in the documentation and/or other materials provided
     11 #       with the distribution.
     12 #     * Neither the name of Google Inc. nor the names of its
     13 #       contributors may be used to endorse or promote products derived
     14 #       from this software without specific prior written permission.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 
     29 import socket
     30 import SocketServer
     31 import StringIO
     32 
     33 from . import compression
     34 from . import constants
     35 
     36 
     37 def LocalQuery(query):
     38   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     39   code = sock.connect_ex(("localhost", constants.CLIENT_PORT))
     40   if code != 0: return None
     41   compression.Send(query, sock)
     42   compression.Send(constants.END_OF_STREAM, sock)
     43   rec = compression.Receiver(sock)
     44   data = None
     45   while not rec.IsDone():
     46     data = rec.Current()
     47     assert data[0] == query[0]
     48     data = data[1]
     49     rec.Advance()
     50   sock.close()
     51   return data
     52 
     53 
     54 class LocalHandler(SocketServer.BaseRequestHandler):
     55   def handle(self):
     56     rec = compression.Receiver(self.request)
     57     while not rec.IsDone():
     58       data = rec.Current()
     59       action = data[0]
     60 
     61       if action == constants.REQUEST_PEERS:
     62         with self.server.daemon.peer_list_lock:
     63           response = [ p.Pack() for p in self.server.daemon.peers
     64                        if p.trusting_me ]
     65         compression.Send([action, response], self.request)
     66 
     67       elif action == constants.UNRESPONSIVE_PEER:
     68         self.server.daemon.DeletePeer(data[1])
     69 
     70       elif action == constants.REQUEST_PUBKEY_FINGERPRINT:
     71         compression.Send([action, self.server.daemon.pubkey_fingerprint],
     72                          self.request)
     73 
     74       elif action == constants.REQUEST_STATUS:
     75         compression.Send([action, self._GetStatusMessage()], self.request)
     76 
     77       elif action == constants.ADD_TRUSTED:
     78         fingerprint = self.server.daemon.CopyToTrusted(data[1])
     79         compression.Send([action, fingerprint], self.request)
     80 
     81       elif action == constants.INFORM_DURATION:
     82         test_key = data[1]
     83         test_duration = data[2]
     84         arch = data[3]
     85         mode = data[4]
     86         self.server.daemon.AddPerfData(test_key, test_duration, arch, mode)
     87 
     88       elif action == constants.UPDATE_PERF:
     89         address = data[1]
     90         perf = data[2]
     91         self.server.daemon.UpdatePeerPerformance(data[1], data[2])
     92 
     93       rec.Advance()
     94     compression.Send(constants.END_OF_STREAM, self.request)
     95 
     96   def _GetStatusMessage(self):
     97     sio = StringIO.StringIO()
     98     sio.write("Peers:\n")
     99     with self.server.daemon.peer_list_lock:
    100       for p in self.server.daemon.peers:
    101         sio.write("%s\n" % p)
    102     sio.write("My own jobs: %d, relative performance: %.2f\n" %
    103               (self.server.daemon.jobs, self.server.daemon.relative_perf))
    104     # Low-priority TODO: Return more information. Ideas:
    105     #   - currently running anything,
    106     #   - time since last job,
    107     #   - time since last repository fetch
    108     #   - number of workpackets/testcases handled since startup
    109     #   - slowest test(s)
    110     result = sio.getvalue()
    111     sio.close()
    112     return result
    113 
    114 
    115 class LocalSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    116   def __init__(self, daemon):
    117     SocketServer.TCPServer.__init__(self, ("localhost", constants.CLIENT_PORT),
    118                                     LocalHandler)
    119     self.daemon = daemon
    120