mirror of https://github.com/zulip/zulip.git
zilencer: Lock the RemoteZulipServer row when inserting data.
This does not ensure that we do not mix data from multiple servers sharing a UUID -- if one has more `RemoteRealmCount` rows, and the other has more `RemoteInstalltionCount` rows, the end result will still be some rows from each server, across the two tables. It does ensure that we will not alternate rows between two servers if both requests are processed at the same time. It also causes submissions to be all-or-nothing in the event of integrity errors. This is not necessarily beneficial, as forward progress is generally useful -- but the integrity errors are resolved in the subsequent commit.
This commit is contained in:
parent
ae836ae007
commit
c6ae3e7242
|
@ -617,6 +617,7 @@ class InstallationCountDataForAnalytics(BaseModel):
|
||||||
|
|
||||||
|
|
||||||
@typed_endpoint
|
@typed_endpoint
|
||||||
|
@transaction.atomic
|
||||||
def remote_server_post_analytics(
|
def remote_server_post_analytics(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
server: RemoteZulipServer,
|
server: RemoteZulipServer,
|
||||||
|
@ -627,6 +628,10 @@ def remote_server_post_analytics(
|
||||||
realms: Optional[Json[List[RealmDataForAnalytics]]] = None,
|
realms: Optional[Json[List[RealmDataForAnalytics]]] = None,
|
||||||
version: Optional[Json[str]] = None,
|
version: Optional[Json[str]] = None,
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
|
# Lock the server, preventing this from racing with other
|
||||||
|
# duplicate submissions of the data
|
||||||
|
server = RemoteZulipServer.objects.select_for_update().get(id=server.id)
|
||||||
|
|
||||||
if version is not None:
|
if version is not None:
|
||||||
version = version[0 : RemoteZulipServer.VERSION_MAX_LENGTH]
|
version = version[0 : RemoteZulipServer.VERSION_MAX_LENGTH]
|
||||||
if version != server.last_version:
|
if version != server.last_version:
|
||||||
|
|
Loading…
Reference in New Issue