mirror of https://github.com/watcha-fr/synapse
Split presence out of master (#9820)
parent
d924827da1
commit
9d25a0ae65
@ -0,0 +1 @@ |
||||
Add experimental support for handling presence on a worker. |
@ -1,50 +0,0 @@ |
||||
# Copyright 2016 OpenMarket Ltd |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
from synapse.replication.tcp.streams import PresenceStream |
||||
from synapse.storage import DataStore |
||||
from synapse.storage.database import DatabasePool |
||||
from synapse.storage.databases.main.presence import PresenceStore |
||||
from synapse.util.caches.stream_change_cache import StreamChangeCache |
||||
|
||||
from ._base import BaseSlavedStore |
||||
from ._slaved_id_tracker import SlavedIdTracker |
||||
|
||||
|
||||
class SlavedPresenceStore(BaseSlavedStore): |
||||
def __init__(self, database: DatabasePool, db_conn, hs): |
||||
super().__init__(database, db_conn, hs) |
||||
self._presence_id_gen = SlavedIdTracker(db_conn, "presence_stream", "stream_id") |
||||
|
||||
self._presence_on_startup = self._get_active_presence(db_conn) # type: ignore |
||||
|
||||
self.presence_stream_cache = StreamChangeCache( |
||||
"PresenceStreamChangeCache", self._presence_id_gen.get_current_token() |
||||
) |
||||
|
||||
_get_active_presence = DataStore._get_active_presence |
||||
take_presence_startup_info = DataStore.take_presence_startup_info |
||||
_get_presence_for_user = PresenceStore.__dict__["_get_presence_for_user"] |
||||
get_presence_for_users = PresenceStore.__dict__["get_presence_for_users"] |
||||
|
||||
def get_current_presence_token(self): |
||||
return self._presence_id_gen.get_current_token() |
||||
|
||||
def process_replication_rows(self, stream_name, instance_name, token, rows): |
||||
if stream_name == PresenceStream.NAME: |
||||
self._presence_id_gen.advance(instance_name, token) |
||||
for row in rows: |
||||
self.presence_stream_cache.entity_has_changed(row.user_id, token) |
||||
self._get_presence_for_user.invalidate((row.user_id,)) |
||||
return super().process_replication_rows(stream_name, instance_name, token, rows) |
@ -0,0 +1,18 @@ |
||||
/* Copyright 2021 The Matrix.org Foundation C.I.C |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
-- Add a column to specify which instance wrote the row. Historic rows have |
||||
-- `NULL`, which indicates that the master instance wrote them. |
||||
ALTER TABLE presence_stream ADD COLUMN instance_name TEXT; |
@ -0,0 +1,20 @@ |
||||
/* Copyright 2021 The Matrix.org Foundation C.I.C |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS presence_stream_sequence; |
||||
|
||||
SELECT setval('presence_stream_sequence', ( |
||||
SELECT COALESCE(MAX(stream_id), 1) FROM presence_stream |
||||
)); |
@ -1,83 +0,0 @@ |
||||
# Copyright 2018 New Vector Ltd |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
from synapse.app.generic_worker import GenericWorkerServer |
||||
|
||||
from tests.server import make_request |
||||
from tests.unittest import HomeserverTestCase |
||||
|
||||
|
||||
class FrontendProxyTests(HomeserverTestCase): |
||||
def make_homeserver(self, reactor, clock): |
||||
|
||||
hs = self.setup_test_homeserver( |
||||
federation_http_client=None, homeserver_to_use=GenericWorkerServer |
||||
) |
||||
|
||||
return hs |
||||
|
||||
def default_config(self): |
||||
c = super().default_config() |
||||
c["worker_app"] = "synapse.app.frontend_proxy" |
||||
|
||||
c["worker_listeners"] = [ |
||||
{ |
||||
"type": "http", |
||||
"port": 8080, |
||||
"bind_addresses": ["0.0.0.0"], |
||||
"resources": [{"names": ["client"]}], |
||||
} |
||||
] |
||||
|
||||
return c |
||||
|
||||
def test_listen_http_with_presence_enabled(self): |
||||
""" |
||||
When presence is on, the stub servlet will not register. |
||||
""" |
||||
# Presence is on |
||||
self.hs.config.use_presence = True |
||||
|
||||
# Listen with the config |
||||
self.hs._listen_http(self.hs.config.worker.worker_listeners[0]) |
||||
|
||||
# Grab the resource from the site that was told to listen |
||||
self.assertEqual(len(self.reactor.tcpServers), 1) |
||||
site = self.reactor.tcpServers[0][1] |
||||
|
||||
channel = make_request(self.reactor, site, "PUT", "presence/a/status") |
||||
|
||||
# 400 + unrecognised, because nothing is registered |
||||
self.assertEqual(channel.code, 400) |
||||
self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED") |
||||
|
||||
def test_listen_http_with_presence_disabled(self): |
||||
""" |
||||
When presence is off, the stub servlet will register. |
||||
""" |
||||
# Presence is off |
||||
self.hs.config.use_presence = False |
||||
|
||||
# Listen with the config |
||||
self.hs._listen_http(self.hs.config.worker.worker_listeners[0]) |
||||
|
||||
# Grab the resource from the site that was told to listen |
||||
self.assertEqual(len(self.reactor.tcpServers), 1) |
||||
site = self.reactor.tcpServers[0][1] |
||||
|
||||
channel = make_request(self.reactor, site, "PUT", "presence/a/status") |
||||
|
||||
# 401, because the stub servlet still checks authentication |
||||
self.assertEqual(channel.code, 401) |
||||
self.assertEqual(channel.json_body["errcode"], "M_MISSING_TOKEN") |
Loading…
Reference in new issue