hgext/remotefilelog/fileserverclient.py
changeset 40502 6d64e2abe8d3
parent 40495 3a333a582d7b
child 40507 e2a1584e9e3f
equal deleted inserted replaced
40501:f21543d7f611 40502:6d64e2abe8d3
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 import hashlib
    10 import hashlib
    11 import io
    11 import io
    12 import os
    12 import os
    13 import struct
       
    14 import threading
    13 import threading
    15 import time
    14 import time
    16 
    15 
    17 from mercurial.i18n import _
    16 from mercurial.i18n import _
    18 from mercurial.node import bin, hex, nullid
    17 from mercurial.node import bin, hex, nullid
    28 from . import (
    27 from . import (
    29     constants,
    28     constants,
    30     contentstore,
    29     contentstore,
    31     lz4wrapper,
    30     lz4wrapper,
    32     metadatastore,
    31     metadatastore,
    33     shallowutil,
       
    34     wirepack,
       
    35 )
    32 )
    36 
    33 
    37 _sshv1peer = sshpeer.sshv1peer
    34 _sshv1peer = sshpeer.sshv1peer
    38 
    35 
    39 # Statistics for debugging
    36 # Statistics for debugging
   313         """
   310         """
   314         if not self.remotecache.connected:
   311         if not self.remotecache.connected:
   315             self.connect()
   312             self.connect()
   316         cache = self.remotecache
   313         cache = self.remotecache
   317         writedata = self.writedata
   314         writedata = self.writedata
   318 
       
   319         if self.ui.configbool('remotefilelog', 'fetchpacks'):
       
   320             self.requestpack(fileids)
       
   321             return
       
   322 
   315 
   323         repo = self.repo
   316         repo = self.repo
   324         count = len(fileids)
   317         count = len(fileids)
   325         request = "get\n%d\n" % count
   318         request = "get\n%d\n" % count
   326         idmap = {}
   319         idmap = {}
   451                                       % (len(data), size))
   444                                       % (len(data), size))
   452 
   445 
   453         self.writedata.addremotefilelognode(filename, bin(node),
   446         self.writedata.addremotefilelognode(filename, bin(node),
   454                                              lz4wrapper.lz4decompress(data))
   447                                              lz4wrapper.lz4decompress(data))
   455 
   448 
   456     def requestpack(self, fileids):
       
   457         """Requests the given file revisions from the server in a pack format.
       
   458 
       
   459         See `remotefilelogserver.getpack` for the file format.
       
   460         """
       
   461         try:
       
   462             with self._connect() as conn:
       
   463                 total = len(fileids)
       
   464                 rcvd = 0
       
   465 
       
   466                 remote = conn.peer
       
   467                 remote._callstream("getpackv1")
       
   468 
       
   469                 self._sendpackrequest(remote, fileids)
       
   470 
       
   471                 packpath = shallowutil.getcachepackpath(
       
   472                     self.repo, constants.FILEPACK_CATEGORY)
       
   473                 pipei = remote._pipei
       
   474                 receiveddata, receivedhistory = wirepack.receivepack(
       
   475                     self.repo.ui, pipei, packpath)
       
   476                 rcvd = len(receiveddata)
       
   477 
       
   478             self.ui.log("remotefilefetchlog",
       
   479                         "Success(pack)\n" if (rcvd==total) else "Fail(pack)\n",
       
   480                         fetched_files = rcvd,
       
   481                         total_to_fetch = total)
       
   482         except Exception:
       
   483             self.ui.log("remotefilefetchlog",
       
   484                         "Fail(pack)\n",
       
   485                         fetched_files = rcvd,
       
   486                         total_to_fetch = total)
       
   487             raise
       
   488 
       
   489     def _sendpackrequest(self, remote, fileids):
       
   490         """Formats and writes the given fileids to the remote as part of a
       
   491         getpackv1 call.
       
   492         """
       
   493         # Sort the requests by name, so we receive requests in batches by name
       
   494         grouped = {}
       
   495         for filename, node in fileids:
       
   496             grouped.setdefault(filename, set()).add(node)
       
   497 
       
   498         # Issue request
       
   499         pipeo = remote._pipeo
       
   500         for filename, nodes in grouped.iteritems():
       
   501             filenamelen = struct.pack(constants.FILENAMESTRUCT, len(filename))
       
   502             countlen = struct.pack(constants.PACKREQUESTCOUNTSTRUCT, len(nodes))
       
   503             rawnodes = ''.join(bin(n) for n in nodes)
       
   504 
       
   505             pipeo.write('%s%s%s%s' % (filenamelen, filename, countlen,
       
   506                                       rawnodes))
       
   507             pipeo.flush()
       
   508         pipeo.write(struct.pack(constants.FILENAMESTRUCT, 0))
       
   509         pipeo.flush()
       
   510 
       
   511     def connect(self):
   449     def connect(self):
   512         if self.cacheprocess:
   450         if self.cacheprocess:
   513             cmd = "%s %s" % (self.cacheprocess, self.writedata._path)
   451             cmd = "%s %s" % (self.cacheprocess, self.writedata._path)
   514             self.remotecache.connect(cmd)
   452             self.remotecache.connect(cmd)
   515         else:
   453         else: