Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2783 from matrix-org/erikj/media_last_accessed
Browse files Browse the repository at this point in the history
Keep track of last access time for local media
  • Loading branch information
erikjohnston authored Jan 17, 2018
2 parents 06db5c4 + 2fb3a28 commit a87006f
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 11 deletions.
32 changes: 25 additions & 7 deletions synapse/rest/media/v1/media_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
logger = logging.getLogger(__name__)


UPDATE_RECENTLY_ACCESSED_REMOTES_TS = 60 * 1000
UPDATE_RECENTLY_ACCESSED_TS = 60 * 1000


class MediaRepository(object):
Expand All @@ -75,6 +75,7 @@ def __init__(self, hs):
self.remote_media_linearizer = Linearizer(name="media_remote")

self.recently_accessed_remotes = set()
self.recently_accessed_locals = set()

# List of StorageProviders where we should search for media and
# potentially upload to.
Expand All @@ -99,19 +100,34 @@ def __init__(self, hs):
)

self.clock.looping_call(
self._update_recently_accessed_remotes,
UPDATE_RECENTLY_ACCESSED_REMOTES_TS
self._update_recently_accessed,
UPDATE_RECENTLY_ACCESSED_TS,
)

@defer.inlineCallbacks
def _update_recently_accessed_remotes(self):
media = self.recently_accessed_remotes
def _update_recently_accessed(self):
remote_media = self.recently_accessed_remotes
self.recently_accessed_remotes = set()

local_media = self.recently_accessed_locals
self.recently_accessed_locals = set()

yield self.store.update_cached_last_access_time(
media, self.clock.time_msec()
local_media, remote_media, self.clock.time_msec()
)

def mark_recently_accessed(self, server_name, media_id):
"""Mark the given media as recently accessed.
Args:
server_name (str|None): Origin server of media, or None if local
media_id (str): The media ID of the content
"""
if server_name:
self.recently_accessed_remotes.add((server_name, media_id))
else:
self.recently_accessed_locals.add(media_id)

@defer.inlineCallbacks
def create_content(self, media_type, upload_name, content, content_length,
auth_user):
Expand Down Expand Up @@ -173,6 +189,8 @@ def get_local_media(self, request, media_id, name):
respond_404(request)
return

self.mark_recently_accessed(None, media_id)

media_type = media_info["media_type"]
media_length = media_info["media_length"]
upload_name = name if name else media_info["upload_name"]
Expand Down Expand Up @@ -204,7 +222,7 @@ def get_remote_media(self, request, server_name, media_id, name):
Deferred: Resolves once a response has successfully been written
to request
"""
self.recently_accessed_remotes.add((server_name, media_id))
self.mark_recently_accessed(server_name, media_id)

# We linearize here to ensure that we don't try and download remote
# media multiple times concurrently
Expand Down
2 changes: 2 additions & 0 deletions synapse/rest/media/v1/thumbnail_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def _async_render_GET(self, request):
yield self._respond_local_thumbnail(
request, media_id, width, height, method, m_type
)
self.media_repo.mark_recently_accessed(server_name, media_id)
else:
if self.dynamic_thumbnails:
yield self._select_or_generate_remote_thumbnail(
Expand All @@ -78,6 +79,7 @@ def _async_render_GET(self, request):
request, server_name, media_id,
width, height, method, m_type
)
self.media_repo.mark_recently_accessed(None, media_id)

@defer.inlineCallbacks
def _respond_local_thumbnail(self, request, media_id, width, height,
Expand Down
23 changes: 20 additions & 3 deletions synapse/storage/media_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,33 @@ def store_cached_remote_media(self, origin, media_id, media_type,
desc="store_cached_remote_media",
)

def update_cached_last_access_time(self, origin_id_tuples, time_ts):
def update_cached_last_access_time(self, local_media, remote_media, time_ms):
"""Updates the last access time of the given media
Args:
local_media (iterable[str]): Set of media_ids
remote_media (iterable[(str, str)]): Set of (server_name, media_id)
time_ms: Current time in milliseconds
"""
def update_cache_txn(txn):
sql = (
"UPDATE remote_media_cache SET last_access_ts = ?"
" WHERE media_origin = ? AND media_id = ?"
)

txn.executemany(sql, (
(time_ts, media_origin, media_id)
for media_origin, media_id in origin_id_tuples
(time_ms, media_origin, media_id)
for media_origin, media_id in remote_media
))

sql = (
"UPDATE local_media_repository SET last_access_ts = ?"
" WHERE media_id = ?"
)

txn.executemany(sql, (
(time_ms, media_id)
for media_id in local_media
))

return self.runInteraction("update_cached_last_access_time", update_cache_txn)
Expand Down
2 changes: 1 addition & 1 deletion synapse/storage/prepare_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

# Remember to update this number every time a change is made to database
# schema files, so the users will be informed on server restarts.
SCHEMA_VERSION = 46
SCHEMA_VERSION = 47

dir_path = os.path.abspath(os.path.dirname(__file__))

Expand Down
16 changes: 16 additions & 0 deletions synapse/storage/schema/delta/47/last_access_media.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* 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.
*/

ALTER TABLE local_media_repository ADD COLUMN last_access_ts BIGINT;

0 comments on commit a87006f

Please sign in to comment.