In #35965 we added `push_device_registered_user_ids` to message &
update_message event.
Zulip servers with such events in their event queues when upgraded
to the new version set push_device_registered_user_ids to empty list,
which is incorrect - it leads to no push notification sent.
This commit adds compatibility code to handle such events. The newly
introduced `push_device_registered` check is used only for events
with `push_device_registered_user_id` present in them.
Previously, we enqueued events to "missedmessage_mobile_notifications"
even for users who had no registered push devices.
'handle_push_notification' later used to perform the check & skip
if there were no registered devices.
This commit avoids putting such events into the
"missedmessage_mobile_notifications" queue at all. By doing so,
we reduce unnecessary churn.
If the client has passed `simplified_presence_events` as true
in the `client_capabilities` parameter of the `POST /register`
request, then the server will send `presence` events with the
`presences` field, which has the user presence data in the
modern API format. When that client capability is false, the
`presence` event will be unchanged and sent with the user
presence data in the legacy format.
Tornado requests try hard to not make SQL queries -- and if they're
necessary, to minimize the number of them. Specifically, both session
objects and user objects are cached in memcached, and we expect that
both of them will have been filled there by Django before any requests
are made to Tornado.
In the event that memcached is flushed, or data is otherwise evicted,
we perform two database queries -- one for the session, and one for
the user. However, the *width* of the latter query has grown
significantly over time, as the Realm object grew more fields, and
recently with the addition of role groups, which require multiple
joins each. This leads to a query which is over 12k of text long, and
results in 319 columns. In the event of a memcached flush, this can
result in a *significant* amount of SQL traffic, as nearly every
active Tornado request will make that query.
We do not wish to narrow the default query for Django; we instead tag
the request in the REST wrapper, and use that to use a much narrower
user cache entry. That narrower cache entry is filled before the
queue is created in Django; we also use it to explicitly set the log
data, so the second "half" of the continued Tornado request does not
need to fetch any user data either when writing its log line.
Because they use different cache keys, this only affects the
session-based `/json/events` endpoint, which caches by user-id; the
`/api/v1/events` endpoint, which uses an API-key cache, keeps its wide
user object. The former is 50% of the total request volume, whereas
the latter is only 2%, so adding an additional cache for it is
unnecessary complexity.
The previous logic over-wrote the requester with the old value if it
had been set to anything in the new request, which it never could have
been. This logic likely stems from confusion in the hasattr
introduced in `89394fc1ebee`.
Always copy the `requester_for_logs` from the first half of the
request.
1ea2f188ce mistakenly introduced a `_rate_limit` member of the
request, which was dutifully transcribed in 3f9a5e1e17. However,
`_rate_limit` was never read from, nor written to -- `_ratelimit` (with
no middle `_`) was the dict that contained rate-limiting data. This
`_ratelimit` dict was later renamed to the `_ratelimits_applied` list,
in e86cfbdbd7, which became the `ratelimits_applied` request note
field in 03693cd27e.
Remove the entirely unused `rate_limit` note, and properly copy the
`ratelimits_applied` data into the new request.
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Now, mark unread operation supports empty topic name.
Adds backward compatibility for:
- `topic` field in the `update_message_flags` event type
when removing `read` flag
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Now, typing operation supports empty topic name.
Adds backward compatibility for:
- `topic` field in the `typing` event type
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Now, toggling topic visibility policy operation supports
empty topic name.
Adds backward compatibility for:
- `topic_name` field in the `user_topic` event type
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Now, message edit operation supports empty topic name.
Adds backward compatibility for:
- `topic` field in the `delete_message` event type
- `orig_subject` and `subject` fields in the `update_message`
event type
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Adds `allow_empty_topic_name` boolean parameter to `GET /messages`
and `GET /messages/{message_id}` endpoints to decide whether the
topic names in the fetched messages can be empty strings.
If False, the topic names in the fetched message will have the
value of `realm_empty_topic_display_name` field in `POST /register`
response replacing "" for channel messages.
This commit is a part of the work to support empty string
as a topic name.
Previously, empty string was not a valid topic name.
Adds a `empty_topic_name` client capability to allow client
to specify whether it supports empty string as a topic name.
Adds backward compatibility for:
- `subject` field in the `message` event type
For an incoming 1:1 DM, the recipient’s own recipient_id is useless to
the recipient themselves. Substitute the sender’s recipient_id, so the
recipient can use recipient_id as documented to uniquely represent the
set of 2 users in this conversation.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit renames the 'queue_json_publish' function to
'queue_json_publish_rollback_unsafe' to reflect the fact that it doesn't
wait for the db transaction (within which it gets called, if any)
to commit and sends event irrespective of commit or rollback.
In most of the cases we don't want to send event in the case of
rollbacks, so the caller should be aware that calling the function
directly is rollback unsafe.
Fixes part of #30489.
`is_archived` field is added to the stream and types.
Include a new `archived_channeels` client capability, to allow clients
to access data on archived channels, without breaking
backwards-compatibility for existing clients that don't know how to
handle these.
Also, included `exclude_archived` parameter to `/get-streams`,
which defaults to `true` as basic clients may not be interested
in archived streams.
This commit renames the 'send_event' function to
'send_event_rollback_unsafe' to reflect the fact that it doesn't
wait for the db transaction (within which it gets called, if any)
to commit and sends event irrespective of commit or rollback.
In most of the cases we don't want to send event in the case of
rollbacks, so the caller should be aware that calling the function
directly is rollback unsafe.
The returns plugin hasn’t been updated for mypy ≥ 1.6. This
annotation is more limited in that it only supports a fixed number of
positional arguments and no keyword arguments, but is good enough for
our purposes.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Collapsing was done incorrectly, as 65c400e06d added `zulip_version`
and `zulip_feature_level`, but did not update the virtual event logic
to copy those new values into the virtual event.
However, it is unlikely that a server will be upgraded multiple times
in quick enough succession for this to ever be relevant. Remove the
logic, which is additional complication for little or no gain.