Compare commits

..

8 Commits

Author SHA1 Message Date
Erik Johnston
54283f3ed4 Update changelog 2019-07-04 11:55:07 +01:00
Erik Johnston
20332b278d 1.1.0 2019-07-04 11:44:09 +01:00
Erik Johnston
f6608a8805 Merge pull request #5615 from matrix-org/anoa/fix_changelog_email_resets
Suggest people use a config file for Docker instead of env vars
2019-07-04 11:40:28 +01:00
Andrew Morgan
426854e7bc Suggest people use a config file for Docker instead of env vars 2019-07-04 11:25:49 +01:00
Richard van der Hoff
463d5a8fde 1.1.0rc2 2019-07-03 10:51:47 +01:00
Richard van der Hoff
91753cae59 Fix a number of "Starting txn from sentinel context" warnings (#5605)
Fixes #5602, #5603
2019-07-03 09:31:27 +01:00
Andrew Morgan
c7b48bd42d Remove SMTP_* env var functionality from docker conf (#5596)
Removes any `SMTP_*` docker container environment variables from having any effect on the default config.

Fixes https://github.com/matrix-org/synapse/issues/5430
2019-07-03 07:14:48 +01:00
Amber Brown
0ee9076ffe Fix media repo breaking (#5593) 2019-07-02 19:01:28 +01:00
14 changed files with 129 additions and 37 deletions

View File

@@ -1,3 +1,33 @@
Synapse 1.1.0 (2019-07-04)
==========================
As of v1.1.0, Synapse no longer supports Python 2, nor Postgres version 9.4.
See the [upgrade notes](UPGRADE.rst#upgrading-to-v110) for more details.
This release also deprecates the use of environment variables to configure the
docker image. See the [docker README](https://github.com/matrix-org/synapse/blob/release-v1.1.0/docker/README.md#legacy-dynamic-configuration-file-support)
for more details.
No changes since 1.1.0rc2.
Synapse 1.1.0rc2 (2019-07-03)
=============================
Bugfixes
--------
- Fix regression in 1.1rc1 where OPTIONS requests to the media repo would fail. ([\#5593](https://github.com/matrix-org/synapse/issues/5593))
- Removed the `SYNAPSE_SMTP_*` docker container environment variables. Using these environment variables prevented the docker container from starting in Synapse v1.0, even though they didn't actually allow any functionality anyway. ([\#5596](https://github.com/matrix-org/synapse/issues/5596))
- Fix a number of "Starting txn from sentinel context" warnings. ([\#5605](https://github.com/matrix-org/synapse/issues/5605))
Internal Changes
----------------
- Update github templates. ([\#5552](https://github.com/matrix-org/synapse/issues/5552))
Synapse 1.1.0rc1 (2019-07-02)
=============================

View File

@@ -1 +0,0 @@
Update github templates.

View File

@@ -1 +0,0 @@
Removed the `SYNAPSE_SMTP_*` docker container environment variables. Using these environment variables prevented the docker container from starting in Synapse v1.0, even though they didn't actually allow any functionality anyway. Users are advised to remove `SYNAPSE_SMTP_HOST`, `SYNAPSE_SMTP_PORT`, `SYNAPSE_SMTP_USER`, `SYNAPSE_SMTP_PASSWORD` and `SYNAPSE_SMTP_FROM` environment variables from their docker run commands.

7
debian/changelog vendored
View File

@@ -1,9 +1,12 @@
matrix-synapse-py3 (1.0.0+nmu1) UNRELEASED; urgency=medium
matrix-synapse-py3 (1.1.0) stable; urgency=medium
[ Silke Hofstra ]
* Include systemd-python to allow logging to the systemd journal.
-- Silke Hofstra <silke@slxh.eu> Wed, 29 May 2019 09:45:29 +0200
[ Synapse Packaging team ]
* New synapse release 1.1.0.
-- Synapse Packaging team <packages@matrix.org> Thu, 04 Jul 2019 11:43:41 +0100
matrix-synapse-py3 (1.0.0) stable; urgency=medium

View File

@@ -35,4 +35,4 @@ try:
except ImportError:
pass
__version__ = "1.1.0rc1"
__version__ = "1.1.0"

View File

@@ -22,6 +22,7 @@ from email.mime.text import MIMEText
from twisted.internet import defer
from synapse.api.errors import StoreError
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.types import UserID
from synapse.util import stringutils
from synapse.util.logcontext import make_deferred_yieldable
@@ -67,7 +68,14 @@ class AccountValidityHandler(object):
)
# Check the renewal emails to send and send them every 30min.
self.clock.looping_call(self.send_renewal_emails, 30 * 60 * 1000)
def send_emails():
# run as a background process to make sure that the database transactions
# have a logcontext to report to
return run_as_background_process(
"send_renewals", self.send_renewal_emails
)
self.clock.looping_call(send_emails, 30 * 60 * 1000)
@defer.inlineCallbacks
def send_renewal_emails(self):

View File

@@ -65,8 +65,8 @@ def wrap_json_request_handler(h):
The handler method must have a signature of "handle_foo(self, request)",
where "request" must be a SynapseRequest.
The handler must return a deferred. If the deferred succeeds we assume that
a response has been sent. If the deferred fails with a SynapseError we use
The handler must return a deferred or a coroutine. If the deferred succeeds
we assume that a response has been sent. If the deferred fails with a SynapseError we use
it to send a JSON response with the appropriate HTTP reponse code. If the
deferred fails with any other type of error we send a 500 reponse.
"""
@@ -353,16 +353,22 @@ class DirectServeResource(resource.Resource):
"""
Render the request, using an asynchronous render handler if it exists.
"""
render_callback_name = "_async_render_" + request.method.decode("ascii")
async_render_callback_name = "_async_render_" + request.method.decode("ascii")
if hasattr(self, render_callback_name):
# Call the handler
callback = getattr(self, render_callback_name)
defer.ensureDeferred(callback(request))
# Try and get the async renderer
callback = getattr(self, async_render_callback_name, None)
return NOT_DONE_YET
else:
super().render(request)
# No async renderer for this request method.
if not callback:
return super().render(request)
resp = callback(request)
# If it's a coroutine, turn it into a Deferred
if isinstance(resp, types.CoroutineType):
defer.ensureDeferred(resp)
return NOT_DONE_YET
def _options_handler(request):

View File

@@ -95,6 +95,7 @@ class PreviewUrlResource(DirectServeResource):
)
def render_OPTIONS(self, request):
request.setHeader(b"Allow", b"OPTIONS, GET")
return respond_with_json(request, 200, {}, send_cors=True)
@wrap_json_request_handler

View File

@@ -253,7 +253,14 @@ class EventsStore(
)
# Read the extrems every 60 minutes
hs.get_clock().looping_call(self._read_forward_extremities, 60 * 60 * 1000)
def read_forward_extremities():
# run as a background process to make sure that the database transactions
# have a logcontext to report to
return run_as_background_process(
"read_forward_extremities", self._read_forward_extremities
)
hs.get_clock().looping_call(read_forward_extremities, 60 * 60 * 1000)
@defer.inlineCallbacks
def _read_forward_extremities(self):

View File

@@ -25,6 +25,7 @@ from twisted.internet import defer
from synapse.api.constants import UserTypes
from synapse.api.errors import Codes, StoreError, ThreepidValidationError
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.storage import background_updates
from synapse.storage._base import SQLBaseStore
from synapse.types import UserID
@@ -619,9 +620,15 @@ class RegistrationStore(
)
# Create a background job for culling expired 3PID validity tokens
hs.get_clock().looping_call(
self.cull_expired_threepid_validation_tokens, THIRTY_MINUTES_IN_MS
)
def start_cull():
# run as a background process to make sure that the database transactions
# have a logcontext to report to
return run_as_background_process(
"cull_expired_threepid_validation_tokens",
self.cull_expired_threepid_validation_tokens,
)
hs.get_clock().looping_call(start_cull, THIRTY_MINUTES_IN_MS)
@defer.inlineCallbacks
def _backgroud_update_set_deactivated_flag(self, progress, batch_size):

View File

@@ -62,7 +62,10 @@ class Clock(object):
def looping_call(self, f, msec):
"""Call a function repeatedly.
Waits `msec` initially before calling `f` for the first time.
Waits `msec` initially before calling `f` for the first time.
Note that the function will be called with no logcontext, so if it is anything
other than trivial, you probably want to wrap it in run_as_background_process.
Args:
f(function): The function to call repeatedly.
@@ -77,6 +80,9 @@ class Clock(object):
def call_later(self, delay, callback, *args, **kwargs):
"""Call something later
Note that the function will be called with no logcontext, so if it is anything
other than trivial, you probably want to wrap it in run_as_background_process.
Args:
delay(float): How long to wait in seconds.
callback(function): Function to call

View File

@@ -24,6 +24,7 @@ See doc/log_contexts.rst for details on how this works.
import logging
import threading
import types
from twisted.internet import defer, threads
@@ -528,8 +529,9 @@ def run_in_background(f, *args, **kwargs):
return from the function, and that the sentinel context is set once the
deferred returned by the function completes.
Useful for wrapping functions that return a deferred which you don't yield
on (for instance because you want to pass it to deferred.gatherResults()).
Useful for wrapping functions that return a deferred or coroutine, which you don't
yield or await on (for instance because you want to pass it to
deferred.gatherResults()).
Note that if you completely discard the result, you should make sure that
`f` doesn't raise any deferred exceptions, otherwise a scary-looking
@@ -544,6 +546,9 @@ def run_in_background(f, *args, **kwargs):
# by synchronous exceptions, so let's turn them into Failures.
return defer.fail()
if isinstance(res, types.CoroutineType):
res = defer.ensureDeferred(res)
if not isinstance(res, defer.Deferred):
return res

View File

@@ -460,3 +460,15 @@ class URLPreviewTests(unittest.HomeserverTestCase):
"error": "DNS resolution failure during URL preview generation",
},
)
def test_OPTIONS(self):
"""
OPTIONS returns the OPTIONS.
"""
request, channel = self.make_request(
"OPTIONS", "url_preview?url=http://example.com", shorthand=False
)
request.render(self.preview_url)
self.pump()
self.assertEqual(channel.code, 200)
self.assertEqual(channel.json_body, {})

View File

@@ -39,24 +39,17 @@ class LoggingContextTestCase(unittest.TestCase):
callback_completed = [False]
def test():
context_one.request = "one"
d = function()
def cb(res):
self._check_test_key("one")
callback_completed[0] = True
return res
d.addCallback(cb)
return d
with LoggingContext() as context_one:
context_one.request = "one"
# fire off function, but don't wait on it.
logcontext.run_in_background(test)
d2 = logcontext.run_in_background(function)
def cb(res):
callback_completed[0] = True
return res
d2.addCallback(cb)
self._check_test_key("one")
@@ -105,6 +98,22 @@ class LoggingContextTestCase(unittest.TestCase):
return self._test_run_in_background(testfunc)
def test_run_in_background_with_coroutine(self):
async def testfunc():
self._check_test_key("one")
d = Clock(reactor).sleep(0)
self.assertIs(LoggingContext.current_context(), LoggingContext.sentinel)
await d
self._check_test_key("one")
return self._test_run_in_background(testfunc)
def test_run_in_background_with_nonblocking_coroutine(self):
async def testfunc():
self._check_test_key("one")
return self._test_run_in_background(testfunc)
@defer.inlineCallbacks
def test_make_deferred_yieldable(self):
# a function which retuns an incomplete deferred, but doesn't follow