comparison mercurial/chgserver.py @ 30739:815e1cefd082

chgserver: make S channel support pager request This patch adds the "pager" support for the S channel. The pager API allows running some subcommands, namely attachio, and waiting for the client to be properly synchronized.
author Jun Wu <quark@fb.com>
date Tue, 10 Jan 2017 06:59:21 +0800
parents 2957409449ac
children 493935e0327a
comparison
equal deleted inserted replaced
30738:a45c0f42271f 30739:815e1cefd082
285 285
286 if type == 'system', waits for: 286 if type == 'system', waits for:
287 287
288 exitcode length (unsigned int), 288 exitcode length (unsigned int),
289 exitcode (int) 289 exitcode (int)
290
291 if type == 'pager', repetitively waits for a command name ending with '\n'
292 and executes it defined by cmdtable, or exits the loop if the command name
293 is empty.
290 """ 294 """
291 def __init__(self, in_, out, channel): 295 def __init__(self, in_, out, channel):
292 self.in_ = in_ 296 self.in_ = in_
293 self.out = out 297 self.out = out
294 self.channel = channel 298 self.channel = channel
295 299
296 def __call__(self, cmd, environ, cwd, type='system'): 300 def __call__(self, cmd, environ, cwd=None, type='system', cmdtable=None):
297 args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')] 301 args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')]
298 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) 302 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems())
299 data = '\0'.join(args) 303 data = '\0'.join(args)
300 self.out.write(struct.pack('>cI', self.channel, len(data))) 304 self.out.write(struct.pack('>cI', self.channel, len(data)))
301 self.out.write(data) 305 self.out.write(data)
306 length, = struct.unpack('>I', length) 310 length, = struct.unpack('>I', length)
307 if length != 4: 311 if length != 4:
308 raise error.Abort(_('invalid response')) 312 raise error.Abort(_('invalid response'))
309 rc, = struct.unpack('>i', self.in_.read(4)) 313 rc, = struct.unpack('>i', self.in_.read(4))
310 return rc 314 return rc
315 elif type == 'pager':
316 while True:
317 cmd = self.in_.readline()[:-1]
318 if not cmd:
319 break
320 if cmdtable and cmd in cmdtable:
321 _log('pager subcommand: %s' % cmd)
322 cmdtable[cmd]()
323 else:
324 raise error.Abort(_('unexpected command: %s') % cmd)
311 else: 325 else:
312 raise error.ProgrammingError('invalid S channel type: %s' % type) 326 raise error.ProgrammingError('invalid S channel type: %s' % type)
313 327
314 _iochannels = [ 328 _iochannels = [
315 # server.ch, ui.fp, mode 329 # server.ch, ui.fp, mode