comparison mercurial/wireprotov2server.py @ 40025:b099e6032f38

wireprotov2: server support for sending content redirects A "content redirect" can be sent in place of inline response content. In terms of code, we model a content redirect as a special type of response object holding the attributes describing that redirect. Sending a content redirect thus becomes as simple as the object emission layer sending an instance of that type. A cacher using externally-addressable content storage could replace the outgoing object stream with an object advertising its location. The bulk of the code in this commit is teaching the output layer which handles the object stream to recognize alternate location objects. The rules are that if an alternate location object is present, it must be the first and only object in the object stream. Otherwise the server emits an error. Differential Revision: https://phab.mercurial-scm.org/D4777
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 26 Sep 2018 18:07:55 -0700
parents 10cf8b116dd8
children 39074a35f7db
comparison
equal deleted inserted replaced
40024:86b22a4cfab1 40025:b099e6032f38
310 310
311 res.status = b'200 OK' 311 res.status = b'200 OK'
312 res.headers[b'Content-Type'] = FRAMINGTYPE 312 res.headers[b'Content-Type'] = FRAMINGTYPE
313 313
314 try: 314 try:
315 objs = dispatch(repo, proto, command['command']) 315 objs = dispatch(repo, proto, command['command'], command['redirect'])
316 316
317 action, meta = reactor.oncommandresponsereadyobjects( 317 action, meta = reactor.oncommandresponsereadyobjects(
318 outstream, command['requestid'], objs) 318 outstream, command['requestid'], objs)
319 319
320 except error.WireprotoCommandError as e: 320 except error.WireprotoCommandError as e:
337 action) 337 action)
338 338
339 def getdispatchrepo(repo, proto, command): 339 def getdispatchrepo(repo, proto, command):
340 return repo.filtered('served') 340 return repo.filtered('served')
341 341
342 def dispatch(repo, proto, command): 342 def dispatch(repo, proto, command, redirect):
343 """Run a wire protocol command. 343 """Run a wire protocol command.
344 344
345 Returns an iterable of objects that will be sent to the client. 345 Returns an iterable of objects that will be sent to the client.
346 """ 346 """
347 repo = getdispatchrepo(repo, proto, command) 347 repo = getdispatchrepo(repo, proto, command)
362 if not entry.cachekeyfn: 362 if not entry.cachekeyfn:
363 for o in callcommand(): 363 for o in callcommand():
364 yield o 364 yield o
365 return 365 return
366 366
367 if redirect:
368 redirecttargets = redirect[b'targets']
369 redirecthashes = redirect[b'hashes']
370 else:
371 redirecttargets = []
372 redirecthashes = []
373
367 cacher = makeresponsecacher(repo, proto, command, args, 374 cacher = makeresponsecacher(repo, proto, command, args,
368 cborutil.streamencode) 375 cborutil.streamencode,
376 redirecttargets=redirecttargets,
377 redirecthashes=redirecthashes)
369 378
370 # But we have no cacher. Do default handling. 379 # But we have no cacher. Do default handling.
371 if not cacher: 380 if not cacher:
372 for o in callcommand(): 381 for o in callcommand():
373 yield o 382 yield o
749 758
750 return pycompat.sysbytes(hasher.hexdigest()) 759 return pycompat.sysbytes(hasher.hexdigest())
751 760
752 return cachekeyfn 761 return cachekeyfn
753 762
754 def makeresponsecacher(repo, proto, command, args, objencoderfn): 763 def makeresponsecacher(repo, proto, command, args, objencoderfn,
764 redirecttargets, redirecthashes):
755 """Construct a cacher for a cacheable command. 765 """Construct a cacher for a cacheable command.
756 766
757 Returns an ``iwireprotocolcommandcacher`` instance. 767 Returns an ``iwireprotocolcommandcacher`` instance.
758 768
759 Extensions can monkeypatch this function to provide custom caching 769 Extensions can monkeypatch this function to provide custom caching