Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
synapse
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Timo Ley
synapse
Commits
950807d9
Commit
950807d9
authored
6 years ago
by
Neil Johnson
Browse files
Options
Downloads
Patches
Plain Diff
fix caching and tests
parent
897c51d2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
synapse/app/homeserver.py
+0
-1
0 additions, 1 deletion
synapse/app/homeserver.py
synapse/storage/monthly_active_users.py
+43
-48
43 additions, 48 deletions
synapse/storage/monthly_active_users.py
tests/storage/test_monthly_active_users.py
+37
-13
37 additions, 13 deletions
tests/storage/test_monthly_active_users.py
with
80 additions
and
62 deletions
synapse/app/homeserver.py
+
0
−
1
View file @
950807d9
...
@@ -64,7 +64,6 @@ from synapse.rest.media.v0.content_repository import ContentRepoResource
...
@@ -64,7 +64,6 @@ from synapse.rest.media.v0.content_repository import ContentRepoResource
from
synapse.server
import
HomeServer
from
synapse.server
import
HomeServer
from
synapse.storage
import
are_all_users_on_domain
from
synapse.storage
import
are_all_users_on_domain
from
synapse.storage.engines
import
IncorrectDatabaseSetup
,
create_engine
from
synapse.storage.engines
import
IncorrectDatabaseSetup
,
create_engine
from
synapse.storage.monthly_active_users
import
MonthlyActiveUsersStore
from
synapse.storage.prepare_database
import
UpgradeDatabaseException
,
prepare_database
from
synapse.storage.prepare_database
import
UpgradeDatabaseException
,
prepare_database
from
synapse.util.caches
import
CACHE_SIZE_FACTOR
from
synapse.util.caches
import
CACHE_SIZE_FACTOR
from
synapse.util.httpresourcetree
import
create_resource_tree
from
synapse.util.httpresourcetree
import
create_resource_tree
...
...
This diff is collapsed.
Click to expand it.
synapse/storage/monthly_active_users.py
+
43
−
48
View file @
950807d9
# -*- coding: utf-8 -*-
# Copyright 2018 New Vector
#
# 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
twisted.internet
import
defer
from
twisted.internet
import
defer
from
synapse.util.caches.descriptors
import
cachedInlineCallbacks
from
synapse.
storage.engines
import
PostgresEngine
,
Sqlite3Engine
from
synapse.
util.caches.descriptors
import
cached
,
cachedInlineCallbacks
from
._base
import
SQLBaseStore
from
._base
import
SQLBaseStore
...
@@ -9,7 +24,7 @@ class MonthlyActiveUsersStore(SQLBaseStore):
...
@@ -9,7 +24,7 @@ class MonthlyActiveUsersStore(SQLBaseStore):
def
__init__
(
self
,
dbconn
,
hs
):
def
__init__
(
self
,
dbconn
,
hs
):
super
(
MonthlyActiveUsersStore
,
self
).
__init__
(
None
,
hs
)
super
(
MonthlyActiveUsersStore
,
self
).
__init__
(
None
,
hs
)
self
.
_clock
=
hs
.
get_clock
()
self
.
_clock
=
hs
.
get_clock
()
self
.
max_mau_value
=
hs
.
config
.
max_mau_value
self
.
hs
=
hs
def
reap_monthly_active_users
(
self
):
def
reap_monthly_active_users
(
self
):
"""
"""
...
@@ -19,62 +34,41 @@ class MonthlyActiveUsersStore(SQLBaseStore):
...
@@ -19,62 +34,41 @@ class MonthlyActiveUsersStore(SQLBaseStore):
Defered()
Defered()
"""
"""
def
_reap_users
(
txn
):
def
_reap_users
(
txn
):
thirty_days_ago
=
(
thirty_days_ago
=
(
int
(
self
.
_clock
.
time_msec
())
-
(
1000
*
60
*
60
*
24
*
30
)
int
(
self
.
_clock
.
time_msec
())
-
(
1000
*
60
*
60
*
24
*
30
)
)
)
if
isinstance
(
self
.
database_engine
,
PostgresEngine
):
sql
=
"
DELETE FROM monthly_active_users WHERE timestamp < ?
"
sql
=
"""
DELETE FROM monthly_active_users
WHERE timestamp < ?
RETURNING user_id
"""
txn
.
execute
(
sql
,
(
thirty_days_ago
,))
res
=
txn
.
fetchall
()
for
r
in
res
:
self
.
is_user_monthly_active
.
invalidate
(
r
)
sql
=
"""
DELETE FROM monthly_active_users
ORDER BY timestamp desc
LIMIT -1 OFFSET ?
RETURNING user_id
"""
txn
.
execute
(
sql
,
(
self
.
max_mau_value
,))
res
=
txn
.
fetchall
()
for
r
in
res
:
self
.
is_user_monthly_active
.
invalidate
(
r
)
print
r
self
.
get_monthly_active_count
.
invalidate
()
elif
isinstance
(
self
.
database_engine
,
Sqlite3Engine
):
sql
=
"
DELETE FROM monthly_active_users WHERE timestamp < ?
"
txn
.
execute
(
sql
,
(
thirty_days_ago
,))
txn
.
execute
(
sql
,
(
thirty_days_ago
,))
sql
=
"""
sql
=
"""
DELETE FROM monthly_active_users
DELETE FROM monthly_active_users
ORDER BY timestamp desc
ORDER BY timestamp desc
LIMIT -1 OFFSET ?
LIMIT -1 OFFSET ?
"""
"""
txn
.
execute
(
sql
,
(
self
.
max_mau_value
,))
txn
.
execute
(
sql
,
(
self
.
hs
.
config
.
max_mau_value
,))
# It seems poor to invalidate the whole cache, but the alternative
res
=
self
.
runInteraction
(
"
reap_monthly_active_users
"
,
_reap_users
)
# is to select then delete which has its own problems.
# It seems poor to invalidate the whole cache, Postgres supports
# It seems unlikely that anyone using this feature on large datasets
# 'Returning' which would allow me to invalidate only the
# would be using sqlite and if they are then there will be
# specific users, but sqlite has no way to do this and instead
# larger perf issues than this one to encourage an upgrade to postgres.
# I would need to SELECT and the DELETE which without locking
# is racy.
# Have resolved to invalidate the whole cache for now and do
# something about it if and when the perf becomes significant
self
.
is_user_monthly_active
.
invalidate_all
()
self
.
get_monthly_active_count
.
invalidate_all
()
return
res
self
.
is_user_monthly_active
.
invalidate_all
()
@cached
(
num_args
=
0
)
self
.
get_monthly_active_count
.
invalidate_all
()
return
self
.
runInteraction
(
"
reap_monthly_active_users
"
,
_reap_users
)
@cachedInlineCallbacks
(
num_args
=
0
)
def
get_monthly_active_count
(
self
):
def
get_monthly_active_count
(
self
):
"""
"""
Generates current count of monthly active users.abs
Generates current count of monthly active users.abs
Return:
Return:
Defered(int): Number of current monthly active users
Defered(int): Number of current monthly active users
"""
"""
def
_count_users
(
txn
):
def
_count_users
(
txn
):
sql
=
"
SELECT COALESCE(count(*), 0) FROM monthly_active_users
"
sql
=
"
SELECT COALESCE(count(*), 0) FROM monthly_active_users
"
...
@@ -91,7 +85,7 @@ class MonthlyActiveUsersStore(SQLBaseStore):
...
@@ -91,7 +85,7 @@ class MonthlyActiveUsersStore(SQLBaseStore):
Deferred(bool): True if a new entry was created, False if an
Deferred(bool): True if a new entry was created, False if an
existing one was updated.
existing one was updated.
"""
"""
return
self
.
_simple_upsert
(
self
.
_simple_upsert
(
desc
=
"
upsert_monthly_active_user
"
,
desc
=
"
upsert_monthly_active_user
"
,
table
=
"
monthly_active_users
"
,
table
=
"
monthly_active_users
"
,
keyvalues
=
{
keyvalues
=
{
...
@@ -102,6 +96,8 @@ class MonthlyActiveUsersStore(SQLBaseStore):
...
@@ -102,6 +96,8 @@ class MonthlyActiveUsersStore(SQLBaseStore):
},
},
lock
=
False
,
lock
=
False
,
)
)
self
.
is_user_monthly_active
.
invalidate
((
user_id
,))
self
.
get_monthly_active_count
.
invalidate
(())
@cachedInlineCallbacks
(
num_args
=
1
)
@cachedInlineCallbacks
(
num_args
=
1
)
def
is_user_monthly_active
(
self
,
user_id
):
def
is_user_monthly_active
(
self
,
user_id
):
...
@@ -120,5 +116,4 @@ class MonthlyActiveUsersStore(SQLBaseStore):
...
@@ -120,5 +116,4 @@ class MonthlyActiveUsersStore(SQLBaseStore):
retcol
=
"
user_id
"
,
retcol
=
"
user_id
"
,
desc
=
"
is_user_monthly_active
"
,
desc
=
"
is_user_monthly_active
"
,
)
)
defer
.
returnValue
(
bool
(
user_present
))
defer
.
returnValue
(
bool
(
user_present
))
This diff is collapsed.
Click to expand it.
tests/storage/test_monthly_active_users.py
+
37
−
13
View file @
950807d9
from
twisted.internet
import
defer
# -*- coding: utf-8 -*-
# Copyright 2018 New Vector
#
# 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.storage.monthly_active_users
import
MonthlyActiveUsersStore
from
twisted.internet
import
defer
import
tests.unittest
import
tests.unittest
import
tests.utils
import
tests.utils
...
@@ -10,20 +23,19 @@ from tests.utils import setup_test_homeserver
...
@@ -10,20 +23,19 @@ from tests.utils import setup_test_homeserver
class
MonthlyActiveUsersTestCase
(
tests
.
unittest
.
TestCase
):
class
MonthlyActiveUsersTestCase
(
tests
.
unittest
.
TestCase
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MonthlyActiveUsersTestCase
,
self
).
__init__
(
*
args
,
**
kwargs
)
super
(
MonthlyActiveUsersTestCase
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
mau
=
None
@defer.inlineCallbacks
@defer.inlineCallbacks
def
setUp
(
self
):
def
setUp
(
self
):
hs
=
yield
setup_test_homeserver
()
self
.
hs
=
yield
setup_test_homeserver
()
self
.
mau
=
MonthlyActiveUsersStore
(
None
,
hs
)
self
.
store
=
self
.
hs
.
get_datastore
(
)
@defer.inlineCallbacks
@defer.inlineCallbacks
def
test_can_insert_and_count_mau
(
self
):
def
test_can_insert_and_count_mau
(
self
):
count
=
yield
self
.
mau
.
get_monthly_active_count
()
count
=
yield
self
.
store
.
get_monthly_active_count
()
self
.
assertEqual
(
0
,
count
)
self
.
assertEqual
(
0
,
count
)
yield
self
.
mau
.
upsert_monthly_active_user
(
"
@user:server
"
)
yield
self
.
store
.
upsert_monthly_active_user
(
"
@user:server
"
)
count
=
yield
self
.
mau
.
get_monthly_active_count
()
count
=
yield
self
.
store
.
get_monthly_active_count
()
self
.
assertEqual
(
1
,
count
)
self
.
assertEqual
(
1
,
count
)
...
@@ -32,11 +44,23 @@ class MonthlyActiveUsersTestCase(tests.unittest.TestCase):
...
@@ -32,11 +44,23 @@ class MonthlyActiveUsersTestCase(tests.unittest.TestCase):
user_id1
=
"
@user1:server
"
user_id1
=
"
@user1:server
"
user_id2
=
"
@user2:server
"
user_id2
=
"
@user2:server
"
user_id3
=
"
@user3:server
"
user_id3
=
"
@user3:server
"
result
=
yield
self
.
mau
.
is_user_monthly_active
(
user_id1
)
result
=
yield
self
.
store
.
is_user_monthly_active
(
user_id1
)
self
.
assertFalse
(
result
)
self
.
assertFalse
(
result
)
yield
self
.
mau
.
upsert_monthly_active_user
(
user_id1
)
yield
self
.
store
.
upsert_monthly_active_user
(
user_id1
)
yield
self
.
mau
.
upsert_monthly_active_user
(
user_id2
)
yield
self
.
store
.
upsert_monthly_active_user
(
user_id2
)
result
=
yield
self
.
mau
.
is_user_monthly_active
(
user_id1
)
result
=
yield
self
.
store
.
is_user_monthly_active
(
user_id1
)
self
.
assertTrue
(
result
)
self
.
assertTrue
(
result
)
result
=
yield
self
.
mau
.
is_user_monthly_active
(
user_id3
)
result
=
yield
self
.
store
.
is_user_monthly_active
(
user_id3
)
self
.
assertFalse
(
result
)
self
.
assertFalse
(
result
)
@defer.inlineCallbacks
def
test_reap_monthly_active_users
(
self
):
self
.
hs
.
config
.
max_mau_value
=
5
initial_users
=
10
for
i
in
range
(
initial_users
):
yield
self
.
store
.
upsert_monthly_active_user
(
"
@user%d:server
"
%
i
)
count
=
yield
self
.
store
.
get_monthly_active_count
()
self
.
assertTrue
(
count
,
initial_users
)
yield
self
.
store
.
reap_monthly_active_users
()
count
=
yield
self
.
store
.
get_monthly_active_count
()
self
.
assertTrue
(
count
,
initial_users
-
self
.
hs
.
config
.
max_mau_value
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment