From 51b1225fc79b9c24d202efb23a971bfb21540dac Mon Sep 17 00:00:00 2001 From: DMRobertson Date: Tue, 5 Jul 2022 12:25:53 +0000 Subject: deploy: b51a0f4be0287f88a747952fb3cc8132d29df4c8 --- latest/development/cas.html | 2 +- latest/development/contributing_guide.html | 14 +- latest/development/database_schema.html | 2 +- latest/development/demo.html | 2 +- latest/development/dependencies.html | 364 +++++++++++++++++++++ latest/development/experimental_features.html | 6 +- latest/development/git.html | 2 +- .../development/internal_documentation/index.html | 2 +- latest/development/releases.html | 2 +- latest/development/room-dag-concepts.html | 2 +- latest/development/saml.html | 2 +- .../synapse_architecture/cancellation.html | 6 +- latest/development/url_previews.html | 2 +- 13 files changed, 392 insertions(+), 16 deletions(-) create mode 100644 latest/development/dependencies.html (limited to 'latest/development') diff --git a/latest/development/cas.html b/latest/development/cas.html index 5adc9578da..9489e46039 100644 --- a/latest/development/cas.html +++ b/latest/development/cas.html @@ -76,7 +76,7 @@ diff --git a/latest/development/contributing_guide.html b/latest/development/contributing_guide.html index 431123734e..3e875cce15 100644 --- a/latest/development/contributing_guide.html +++ b/latest/development/contributing_guide.html @@ -76,7 +76,7 @@ @@ -342,6 +342,18 @@ Here is how to run your local Synapse checkout against your local Complement che

To run a specific test, you can specify the whole name structure:

COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages/parallel/Historical_events_resolve_in_the_correct_order
 
+

The above will run a monolithic (single-process) Synapse with SQLite as the database. For other configurations, try:

+ +

Prettier formatting with gotestfmt

+

If you want to format the output of the tests the same way as it looks in CI, +install gotestfmt.

+

You can then use this incantation to format the tests appropriately:

+
COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -json | gotestfmt -hide successful-tests
+
+

(Remove -hide successful-tests if you don't want to hide successful tests.)

Access database for homeserver after Complement test runs.

If you're curious what the database looks like after you run some tests, here are some steps to get you going in Synapse:

    diff --git a/latest/development/database_schema.html b/latest/development/database_schema.html index 7c0c9a6eb2..4647bfed38 100644 --- a/latest/development/database_schema.html +++ b/latest/development/database_schema.html @@ -76,7 +76,7 @@ diff --git a/latest/development/demo.html b/latest/development/demo.html index b8e499587a..3622336657 100644 --- a/latest/development/demo.html +++ b/latest/development/demo.html @@ -76,7 +76,7 @@ diff --git a/latest/development/dependencies.html b/latest/development/dependencies.html new file mode 100644 index 0000000000..46b2ac0bae --- /dev/null +++ b/latest/development/dependencies.html @@ -0,0 +1,364 @@ + + + + + + Dependency management - Synapse + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + +
    +
    + +
    + +
    + +

    Managing dependencies with Poetry

    +

    This is a quick cheat sheet for developers on how to use poetry.

    +

    Background

    +

    Synapse uses a variety of third-party Python packages to function as a homeserver. +Some of these are direct dependencies, listed in pyproject.toml under the +[tool.poetry.dependencies] section. The rest are transitive dependencies (the +things that our direct dependencies themselves depend on, and so on recursively.)

    +

    We maintain a locked list of all our dependencies (transitive included) so that +we can track exactly which version of each dependency appears in a given release. +See here +for discussion of why we wanted this for Synapse. We chose to use +poetry to manage this locked list; see +this comment +for the reasoning.

    +

    The locked dependencies get included in our "self-contained" releases: namely, +our docker images and our debian packages. We also use the locked dependencies +in development and our continuous integration.

    +

    Separately, our "broad" dependencies—the version ranges specified in +pyproject.toml—are included as metadata in our "sdists" and "wheels" uploaded +to PyPI. Installing from PyPI or from +the Synapse source tree directly will not use the locked dependencies; instead, +they'll pull in the latest version of each package available at install time.

    +

    Example dependency

    +

    An example may help. We have a broad dependency on +phonenumbers, as declared in +this snippet from pyproject.toml as of Synapse 1.57:

    +
    [tool.poetry.dependencies]
    +# ...
    +phonenumbers = ">=8.2.0"
    +
    +

    In our lockfile this is +pinned +to version 8.12.44, even though +newer versions are available.

    +
    [[package]]
    +name = "phonenumbers"
    +version = "8.12.44"
    +description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
    +category = "main"
    +optional = false
    +python-versions = "*"
    +
    +

    The lockfile also includes a +cryptographic checksum +of the sdists and wheels provided for this version of phonenumbers.

    +
    [metadata.files]
    +# ...
    +phonenumbers = [
    +    {file = "phonenumbers-8.12.44-py2.py3-none-any.whl", hash = "sha256:cc1299cf37b309ecab6214297663ab86cb3d64ae37fd5b88e904fe7983a874a6"},
    +    {file = "phonenumbers-8.12.44.tar.gz", hash = "sha256:26cfd0257d1704fe2f88caff2caabb70d16a877b1e65b6aae51f9fbbe10aa8ce"},
    +]
    +
    +

    We can see this pinned version inside the docker image for that release:

    +
    $ docker pull matrixdotorg/synapse:v1.57.0
    +...
    +$ docker run --entrypoint pip matrixdotorg/synapse:v1.57.0 show phonenumbers
    +Name: phonenumbers
    +Version: 8.12.44
    +Summary: Python version of Google's common library for parsing, formatting, storing and validating international phone numbers.
    +Home-page: https://github.com/daviddrysdale/python-phonenumbers
    +Author: David Drysdale
    +Author-email: dmd@lurklurk.org
    +License: Apache License 2.0
    +Location: /usr/local/lib/python3.9/site-packages
    +Requires:
    +Required-by: matrix-synapse
    +
    +

    Whereas the wheel metadata just contains the broad dependencies:

    +
    $ cd /tmp
    +$ wget https://files.pythonhosted.org/packages/ca/5e/d722d572cc5b3092402b783d6b7185901b444427633bd8a6b00ea0dd41b7/matrix_synapse-1.57.0rc1-py3-none-any.whl
    +...
    +$ unzip -c matrix_synapse-1.57.0rc1-py3-none-any.whl matrix_synapse-1.57.0rc1.dist-info/METADATA | grep phonenumbers
    +Requires-Dist: phonenumbers (>=8.2.0)
    +
    +

    Tooling recommendation: direnv

    +

    direnv is a tool for activating environments in your +shell inside a given directory. Its support for poetry is unofficial (a +community wiki recipe only), but works solidly in our experience. We thoroughly +recommend it for daily use. To use it:

    +
      +
    1. Install direnv - it's likely +packaged for your system already.
    2. +
    3. Teach direnv about poetry. The shell config here +needs to be added to ~/.config/direnv/direnvrc (or more generally $XDG_CONFIG_HOME/direnv/direnvrc).
    4. +
    5. Mark the synapse checkout as a poetry project: echo layout poetry > .envrc.
    6. +
    7. Convince yourself that you trust this .envrc configuration and project. +Then formally confirm this to direnv by running direnv allow.
    8. +
    +

    Then whenever you navigate to the synapse checkout, you should be able to run +e.g. mypy instead of poetry run mypy; python instead of +poetry run python; and your shell commands will automatically run in the +context of poetry's venv, without having to run poetry shell beforehand.

    +

    How do I...

    +

    ...reset my venv to the locked environment?

    +
    poetry install --extras all --remove-untracked
    +
    +

    ...run a command in the poetry virtualenv?

    +

    Use poetry run cmd args when you need the python virtualenv context. +To avoid typing poetry run all the time, you can run poetry shell +to start a new shell in the poetry virtualenv context. Within poetry shell, +python, pip, mypy, trial, etc. are all run inside the project virtualenv +and isolated from the rest o the system.

    +

    Roughly speaking, the translation from a traditional virtualenv is:

    +
      +
    • env/bin/activate -> poetry shell, and
    • +
    • deactivate -> close the terminal (Ctrl-D, exit, etc.)
    • +
    +

    See also the direnv recommendation above, which makes poetry run and +poetry shell unnecessary.

    +

    ...inspect the poetry virtualenv?

    +

    Some suggestions:

    +
    # Current env only
    +poetry env info
    +# All envs: this allows you to have e.g. a poetry managed venv for Python 3.7,
    +# and another for Python 3.10.
    +poetry env list --full-path
    +poetry run pip list
    +
    +

    Note that poetry show describes the abstract lock file rather than your +on-disk environment. With that said, poetry show --tree can sometimes be +useful.

    +

    ...add a new dependency?

    +

    Either:

    +
      +
    • manually update pyproject.toml; then poetry lock --no-update; or else
    • +
    • poetry add packagename. See poetry add --help; note the --dev, +--extras and --optional flags in particular. +
        +
      • NB: this specifies the new package with a version given by a "caret bound". This won't get forced to its lowest version in the old deps CI job: see this TODO.
      • +
      +
    • +
    +

    Include the updated pyproject.toml and poetry.lock files in your commit.

    +

    ...remove a dependency?

    +

    This is not done often and is untested, but

    +
    poetry remove packagename
    +
    +

    ought to do the trick. Alternatively, manually update pyproject.toml and +poetry lock --no-update. Include the updated pyproject.toml and poetry.lock` +files in your commit.

    +

    ...update the version range for an existing dependency?

    +

    Best done by manually editing pyproject.toml, then poetry lock --no-update. +Include the updated pyproject.toml and poetry.lock in your commit.

    +

    ...update a dependency in the locked environment?

    +

    Use

    +
    poetry update packagename
    +
    +

    to use the latest version of packagename in the locked environment, without +affecting the broad dependencies listed in the wheel.

    +

    There doesn't seem to be a way to do this whilst locking a specific version of +packagename. We can workaround this (crudely) as follows:

    +
    poetry add packagename==1.2.3
    +# This should update pyproject.lock.
    +
    +# Now undo the changes to pyproject.toml. For example
    +# git restore pyproject.toml
    +
    +# Get poetry to recompute the content-hash of pyproject.toml without changing
    +# the locked package versions.
    +poetry lock --no-update
    +
    +

    Either way, include the updated poetry.lock file in your commit.

    +

    ...export a requirements.txt file?

    +
    poetry export --extras all
    +
    +

    Be wary of bugs in poetry export and pip install -r requirements.txt.

    +

    Note: poetry export will be made a plugin in Poetry 1.2. Additional config may +be required.

    +

    ...build a test wheel?

    +

    I usually use

    +
    poetry run pip install build && poetry run python -m build
    +
    +

    because build is a standardish tool which +doesn't require poetry. (It's what we use in CI too). However, you could try +poetry build too.

    + +
    + + +
    +
    + + + +
    + + + + + + + + + + + + + \ No newline at end of file diff --git a/latest/development/experimental_features.html b/latest/development/experimental_features.html index cd6104999e..b82202c3b3 100644 --- a/latest/development/experimental_features.html +++ b/latest/development/experimental_features.html @@ -76,7 +76,7 @@ @@ -187,7 +187,7 @@ configuration key (see the synapse.config.experimental file) and ei -
    @@ -199,7 +199,7 @@ configuration key (see the synapse.config.experimental file) and ei - diff --git a/latest/development/git.html b/latest/development/git.html index 9a1c2bdd79..a3e299777c 100644 --- a/latest/development/git.html +++ b/latest/development/git.html @@ -76,7 +76,7 @@ diff --git a/latest/development/internal_documentation/index.html b/latest/development/internal_documentation/index.html index fe8ab238f2..f85324af4a 100644 --- a/latest/development/internal_documentation/index.html +++ b/latest/development/internal_documentation/index.html @@ -76,7 +76,7 @@ diff --git a/latest/development/releases.html b/latest/development/releases.html index 7a26758cb1..5a4afdfb69 100644 --- a/latest/development/releases.html +++ b/latest/development/releases.html @@ -76,7 +76,7 @@ diff --git a/latest/development/room-dag-concepts.html b/latest/development/room-dag-concepts.html index 4b34c6d62f..406e7c57fc 100644 --- a/latest/development/room-dag-concepts.html +++ b/latest/development/room-dag-concepts.html @@ -76,7 +76,7 @@ diff --git a/latest/development/saml.html b/latest/development/saml.html index 860d69cf8a..3f0673a20e 100644 --- a/latest/development/saml.html +++ b/latest/development/saml.html @@ -76,7 +76,7 @@ diff --git a/latest/development/synapse_architecture/cancellation.html b/latest/development/synapse_architecture/cancellation.html index d67f9eb56c..99ef9af8bb 100644 --- a/latest/development/synapse_architecture/cancellation.html +++ b/latest/development/synapse_architecture/cancellation.html @@ -76,7 +76,7 @@ @@ -498,7 +498,7 @@ with LoggingContext("request-1"):