Mercurial > hg
view Makefile @ 40022:33eb670e2834
wireprotov2: define semantics for content redirects
When I implemented the clonebundles feature and deployed it on
hg.mozilla.org using Amazon S3 as a content server, server-side CPU
and bandwidth usage dropped off a cliff and a ton of server scaling
headaches went away pretty much the instant clients with support for
clonebundles were rolled out to Firefox CI.
An obvious takeaway from that experience was that offloading server
load to scalable file servers - potentially backed by a CDN - is a
really good idea. Another takeaway was that Mercurial's wire protocol
wasn't in a good position to support data offload generally.
In wire protocol version 1, there isn't a mechanism in the protocol to
say "grab the data from over here instead." For HTTP, we could teach
the client to follow HTTP redirects. Or we could invent a media type
that encoded redirects inline. But for SSH, we were pretty much out of
luck because that protocol wasn't very flexible.
Wire protocol version 2 offers the opportunity to do something better.
The recent generic server-side content caching layer in the wire
protocol version 2 server demonstrated that it is possible to have
drop-in caching of responses to command requests. This by itself
adds tons of value and already makes the built-in server much more
scalable. But I don't want to stop there.
The existing server-side caching implementation has a big weakness:
it requires the server to send data to the client. This means that
the Mercurial server is potentially sending gigabytes of data to
thousands of clients. This is problematic because compared to scaling
static file servers, scaling dynamic servers is *hard*.
A solution to this is to "offload" serving of content to something
that isn't the Mercurial server. By offloading content serving, you
turn the Mercurial server from a centralized monolithic service to
a distributed mostly-indexing service. Assuming high rates of content
offload, this should drastically reduce the total work performed by
the Mercurial server, both in terms of CPU and data transfer. This
will make Mercurial servers vastly easier to scale.
This commit defines the semantics for "content redirects" in wire
protocol version 2. Essentially:
* Servers advertise the set of locations a response could be served
from.
* When making requests, clients advertise the set of locations they
are willing to fetch content from.
* Servers can then replace the inline response with one that says
"get the response from over here instead."
This feature - when fully implemented - will allow extending the
server-side caching layer to facilitate such things as integrating
your server-side cache with a scalable blob store (such as S3 or
a CDN) and offloading most data transfer to that external service.
This feature could also be leveraged for load balancing. e.g.
requests could come into a central server and then get redirected
to an available mirror depending on server availability or locality.
There's tons of potential :)
Differential Revision: https://phab.mercurial-scm.org/D4774
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 26 Sep 2018 18:02:06 -0700 |
parents | 4ca5932065ca |
children | d0a6b2c8f8b6 |
line wrap: on
line source
# If you want to change PREFIX, do not just edit it below. The changed # value wont get passed on to recursive make calls. You should instead # override the variable on the command like: # # % make PREFIX=/opt/ install export PREFIX=/usr/local PYTHON=python $(eval HGROOT := $(shell pwd)) HGPYTHONS ?= $(HGROOT)/build/pythons PURE= PYFILESCMD=find mercurial hgext doc -name '*.py' PYFILES:=$(shell $(PYFILESCMD)) DOCFILES=mercurial/help/*.txt export LANGUAGE=C export LC_ALL=C TESTFLAGS ?= $(shell echo $$HGTESTFLAGS) OSXVERSIONFLAGS ?= $(shell echo $$OSXVERSIONFLAGS) # Set this to e.g. "mingw32" to use a non-default compiler. COMPILER= COMPILERFLAG_tmp_ = COMPILERFLAG_tmp_${COMPILER} ?= -c $(COMPILER) COMPILERFLAG=${COMPILERFLAG_tmp_${COMPILER}} help: @echo 'Commonly used make targets:' @echo ' all - build program and documentation' @echo ' install - install program and man pages to $$PREFIX ($(PREFIX))' @echo ' install-home - install with setup.py install --home=$$HOME ($(HOME))' @echo ' local - build for inplace usage' @echo ' tests - run all tests in the automatic test suite' @echo ' test-foo - run only specified tests (e.g. test-merge1.t)' @echo ' dist - run all tests and create a source tarball in dist/' @echo ' clean - remove files created by other targets' @echo ' (except installed files or dist source tarball)' @echo ' update-pot - update i18n/hg.pot' @echo @echo 'Example for a system-wide installation under /usr/local:' @echo ' make all && su -c "make install" && hg version' @echo @echo 'Example for a local installation (usable in this directory):' @echo ' make local && ./hg version' all: build doc local: $(PYTHON) setup.py $(PURE) \ build_py -c -d . \ build_ext $(COMPILERFLAG) -i \ build_hgexe $(COMPILERFLAG) -i \ build_mo env HGRCPATH= $(PYTHON) hg version build: $(PYTHON) setup.py $(PURE) build $(COMPILERFLAG) wheel: FORCE_SETUPTOOLS=1 $(PYTHON) setup.py $(PURE) bdist_wheel $(COMPILERFLAG) doc: $(MAKE) -C doc cleanbutpackages: -$(PYTHON) setup.py clean --all # ignore errors from this command find contrib doc hgext hgext3rd i18n mercurial tests hgdemandimport \ \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';' rm -f MANIFEST MANIFEST.in hgext/__index__.py tests/*.err rm -f mercurial/__modulepolicy__.py if test -d .hg; then rm -f mercurial/__version__.py; fi rm -rf build mercurial/locale $(MAKE) -C doc clean $(MAKE) -C contrib/chg distclean clean: cleanbutpackages rm -rf packages install: install-bin install-doc install-bin: build $(PYTHON) setup.py $(PURE) install --root="$(DESTDIR)/" --prefix="$(PREFIX)" --force install-doc: doc cd doc && $(MAKE) $(MFLAGS) install install-home: install-home-bin install-home-doc install-home-bin: build $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --prefix="" --force install-home-doc: doc cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install MANIFEST-doc: $(MAKE) -C doc MANIFEST MANIFEST.in: MANIFEST-doc hg manifest | sed -e 's/^/include /' > MANIFEST.in echo include mercurial/__version__.py >> MANIFEST.in sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in dist: tests dist-notests dist-notests: doc MANIFEST.in TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist check: tests tests: cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) test-%: cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@ testpy-%: @echo Looking for Python $* in $(HGPYTHONS) [ -e $(HGPYTHONS)/$*/bin/python ] || ( \ cd $$(mktemp --directory --tmpdir) && \ $(MAKE) -f $(HGROOT)/contrib/Makefile.python PYTHONVER=$* PREFIX=$(HGPYTHONS)/$* python ) cd tests && $(HGPYTHONS)/$*/bin/python run-tests.py $(TESTFLAGS) check-code: hg manifest | xargs python contrib/check-code.py format-c: clang-format --style file -i \ `hg files 'set:(**.c or **.cc or **.h) and not "listfile:contrib/clang-format-ignorelist"'` update-pot: i18n/hg.pot i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n/posplit i18n/hggettext $(PYTHON) i18n/hggettext mercurial/commands.py \ hgext/*.py hgext/*/__init__.py \ mercurial/fileset.py mercurial/revset.py \ mercurial/templatefilters.py \ mercurial/templatefuncs.py \ mercurial/templatekw.py \ mercurial/filemerge.py \ mercurial/hgweb/webcommands.py \ mercurial/util.py \ $(DOCFILES) > i18n/hg.pot.tmp # All strings marked for translation in Mercurial contain # ASCII characters only. But some files contain string # literals like this '\037\213'. xgettext thinks it has to # parse them even though they are not marked for translation. # Extracting with an explicit encoding of ISO-8859-1 will make # xgettext "parse" and ignore them. $(PYFILESCMD) | xargs \ xgettext --package-name "Mercurial" \ --msgid-bugs-address "<mercurial-devel@mercurial-scm.org>" \ --copyright-holder "Matt Mackall <mpm@selenic.com> and others" \ --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \ -d hg -p i18n -o hg.pot.tmp $(PYTHON) i18n/posplit i18n/hg.pot.tmp # The target file is not created before the last step. So it never is in # an intermediate state. mv -f i18n/hg.pot.tmp i18n/hg.pot %.po: i18n/hg.pot # work on a temporary copy for never having a half completed target cp $@ $@.tmp msgmerge --no-location --update $@.tmp $^ mv -f $@.tmp $@ # Packaging targets packaging_targets := \ centos5 \ centos6 \ centos7 \ deb \ docker-centos5 \ docker-centos6 \ docker-centos7 \ docker-debian-jessie \ docker-debian-stretch \ docker-fedora20 \ docker-fedora21 \ docker-fedora28 \ docker-ubuntu-trusty \ docker-ubuntu-trusty-ppa \ docker-ubuntu-xenial \ docker-ubuntu-xenial-ppa \ docker-ubuntu-artful \ docker-ubuntu-artful-ppa \ docker-ubuntu-bionic \ docker-ubuntu-bionic-ppa \ fedora20 \ fedora21 \ fedora28 \ linux-wheels \ linux-wheels-x86_64 \ linux-wheels-i686 \ ppa # Forward packaging targets for convenience. $(packaging_targets): $(MAKE) -C contrib/packaging $@ osx: rm -rf build/mercurial /usr/bin/python2.7 setup.py install --optimize=1 \ --root=build/mercurial/ --prefix=/usr/local/ \ --install-lib=/Library/Python/2.7/site-packages/ make -C doc all install DESTDIR="$(PWD)/build/mercurial/" # Place a bogon .DS_Store file in the target dir so we can be # sure it doesn't get included in the final package. touch build/mercurial/.DS_Store # install zsh completions - this location appears to be # searched by default as of macOS Sierra. install -d build/mercurial/usr/local/share/zsh/site-functions/ install -m 0644 contrib/zsh_completion build/mercurial/usr/local/share/zsh/site-functions/_hg # install bash completions - there doesn't appear to be a # place that's searched by default for bash, so we'll follow # the lead of Apple's git install and just put it in a # location of our own. install -d build/mercurial/usr/local/hg/contrib/ install -m 0644 contrib/bash_completion build/mercurial/usr/local/hg/contrib/hg-completion.bash make -C contrib/chg \ HGPATH=/usr/local/bin/hg \ PYTHON=/usr/bin/python2.7 \ HGEXTDIR=/Library/Python/2.7/site-packages/hgext \ DESTDIR=../../build/mercurial \ PREFIX=/usr/local \ clean install mkdir -p $${OUTPUTDIR:-dist} HGVER=$$(python contrib/genosxversion.py $(OSXVERSIONFLAGS) build/mercurial/Library/Python/2.7/site-packages/mercurial/__version__.py) && \ OSXVER=$$(sw_vers -productVersion | cut -d. -f1,2) && \ pkgbuild --filter \\.DS_Store --root build/mercurial/ \ --identifier org.mercurial-scm.mercurial \ --version "$${HGVER}" \ build/mercurial.pkg && \ productbuild --distribution contrib/packaging/macosx/distribution.xml \ --package-path build/ \ --version "$${HGVER}" \ --resources contrib/packaging/macosx/ \ "$${OUTPUTDIR:-dist/}"/Mercurial-"$${HGVER}"-macosx"$${OSXVER}".pkg .PHONY: help all local build doc cleanbutpackages clean install install-bin \ install-doc install-home install-home-bin install-home-doc \ dist dist-notests check tests check-code format-c update-pot \ $(packaging_targets) \ osx