Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/commands.py @ 635:85e2209d401c
Protocol switch from using generators to stream-like objects.
This allows the the pull side to precisely control how much data is
read so that another encapsulation layer is not needed.
An http client gets a response with a finite size. Because ssh clients
need to keep the stream open, we must not read more data than is sent
in a response. But due to the streaming nature of the changegroup
scheme, only the piece that's parsing the data knows how far it's
allowed to read.
This means the generator scheme isn't fine-grained enough. Instead we
need file-like objects with a read(x) method. This switches everything
for push/pull over to using file-like objects rather than generators.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 06 Jul 2005 22:20:12 -0800 |
parents | da5378d39269 |
children | 35f7adfefa69 |
comparison
equal
deleted
inserted
replaced
634:da5378d39269 | 635:85e2209d401c |
---|---|
865 | 865 |
866 def serve(ui, repo, **opts): | 866 def serve(ui, repo, **opts): |
867 """export the repository via HTTP""" | 867 """export the repository via HTTP""" |
868 | 868 |
869 if opts["stdio"]: | 869 if opts["stdio"]: |
870 fin, fout = sys.stdin, sys.stdout | |
871 sys.stdout = sys.stderr | |
872 | |
870 def getarg(): | 873 def getarg(): |
871 argline = sys.stdin.readline()[:-1] | 874 argline = fin.readline()[:-1] |
872 arg, l = argline.split() | 875 arg, l = argline.split() |
873 val = sys.stdin.read(int(l)) | 876 val = fin.read(int(l)) |
874 return arg, val | 877 return arg, val |
875 def respond(v): | 878 def respond(v): |
876 sys.stdout.write("%d\n" % len(v)) | 879 fout.write("%d\n" % len(v)) |
877 sys.stdout.write(v) | 880 fout.write(v) |
878 sys.stdout.flush() | 881 fout.flush() |
879 | 882 |
880 while 1: | 883 while 1: |
881 cmd = sys.stdin.readline()[:-1] | 884 cmd = fin.readline()[:-1] |
882 if cmd == '': | 885 if cmd == '': |
883 return | 886 return |
884 if cmd == "heads": | 887 if cmd == "heads": |
885 h = repo.heads() | 888 h = repo.heads() |
886 respond(" ".join(map(hg.hex, h)) + "\n") | 889 respond(" ".join(map(hg.hex, h)) + "\n") |
901 elif cmd == "changegroup": | 904 elif cmd == "changegroup": |
902 nodes = [] | 905 nodes = [] |
903 arg, roots = getarg() | 906 arg, roots = getarg() |
904 nodes = map(hg.bin, roots.split(" ")) | 907 nodes = map(hg.bin, roots.split(" ")) |
905 | 908 |
906 b = [] | 909 cg = repo.changegroup(nodes) |
907 t = 0 | 910 while 1: |
908 for chunk in repo.changegroup(nodes): | 911 d = cg.read(4096) |
909 t += len(chunk) | 912 if not d: break |
910 b.append(chunk) | 913 fout.write(d) |
911 if t > 4096: | 914 |
912 sys.stdout.write(struct.pack(">l", t)) | 915 out.flush() |
913 for c in b: | |
914 sys.stdout.write(c) | |
915 t = 0 | |
916 b = [] | |
917 | |
918 sys.stdout.write(struct.pack(">l", t)) | |
919 for c in b: | |
920 sys.stdout.write(c) | |
921 | |
922 sys.stdout.write(struct.pack(">l", -1)) | |
923 sys.stdout.flush() | |
924 | 916 |
925 def openlog(opt, default): | 917 def openlog(opt, default): |
926 if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') | 918 if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') |
927 else: return default | 919 else: return default |
928 | 920 |