Compare commits
8 Commits
anoa/remov
...
release-v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54283f3ed4 | ||
|
|
20332b278d | ||
|
|
f6608a8805 | ||
|
|
426854e7bc | ||
|
|
463d5a8fde | ||
|
|
91753cae59 | ||
|
|
c7b48bd42d | ||
|
|
0ee9076ffe |
30
CHANGES.md
30
CHANGES.md
@@ -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)
|
||||
=============================
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Update github templates.
|
||||
7
debian/changelog
vendored
7
debian/changelog
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -207,22 +207,3 @@ perspectives:
|
||||
|
||||
password_config:
|
||||
enabled: true
|
||||
|
||||
{% if SYNAPSE_SMTP_HOST %}
|
||||
email:
|
||||
enable_notifs: false
|
||||
smtp_host: "{{ SYNAPSE_SMTP_HOST }}"
|
||||
smtp_port: {{ SYNAPSE_SMTP_PORT or "25" }}
|
||||
smtp_user: "{{ SYNAPSE_SMTP_USER }}"
|
||||
smtp_pass: "{{ SYNAPSE_SMTP_PASSWORD }}"
|
||||
require_transport_security: False
|
||||
notif_from: "{{ SYNAPSE_SMTP_FROM or "hostmaster@" + SYNAPSE_SERVER_NAME }}"
|
||||
app_name: Matrix
|
||||
# if template_dir is unset, uses the example templates that are part of
|
||||
# the Synapse distribution.
|
||||
#template_dir: res/templates
|
||||
notif_template_html: notif_mail.html
|
||||
notif_template_text: notif_mail.txt
|
||||
notif_for_new_users: True
|
||||
riot_base_url: "https://{{ SYNAPSE_SERVER_NAME }}"
|
||||
{% endif %}
|
||||
|
||||
@@ -35,4 +35,4 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__version__ = "1.1.0rc1"
|
||||
__version__ = "1.1.0"
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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, {})
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user