Revert "create_user: Use transaction.atomic decorator for do_create_user."

This reverts commit 851d68e0fc.

That commit widened how long the transaction is open, which made it
much more likely that after the user was created in the transaction,
and the memcached caches were flushed, some other request will fill
the `get_realm_user_dicts` cache with data which did not include the
new user (because it had not been committed yet).

If a user creation request lost this race, the user would, upon first
request to `/`, get a blank page and a Javascript error:

    Unknown user_id in get_by_user_id: 12345

...where 12345 was their own user-id.  This error would persist until
the cache expired (in 7 days) or something else expunged it.

Reverting this does not prevent the race, as the post_save hook's call
to flush_user_profile is still in a transaction (and has been since
168f241ff0), and thus leaves the potential race window open.
However, it much shortens the potential window of opportunity, and is
a reasonable short-term stopgap.
This commit is contained in:
Alex Vandiver
2023-02-17 20:44:51 -05:00
committed by Alex Vandiver
parent 7feda75c5f
commit 8998aa00cd
10 changed files with 145 additions and 199 deletions

View File

@@ -440,33 +440,20 @@ class NormalActionsTest(BaseAction):
for i in range(3):
content = "mentioning... @**" + user.full_name + "** hello " + str(i)
self.verify_action(
lambda: self.send_stream_message(
self.example_user("cordelia"),
"Verona",
content,
capture_on_commit_callbacks=False,
),
lambda: self.send_stream_message(self.example_user("cordelia"), "Verona", content),
)
def test_wildcard_mentioned_send_message_events(self) -> None:
for i in range(3):
content = "mentioning... @**all** hello " + str(i)
self.verify_action(
lambda: self.send_stream_message(
self.example_user("cordelia"),
"Verona",
content,
capture_on_commit_callbacks=False,
),
lambda: self.send_stream_message(self.example_user("cordelia"), "Verona", content),
)
def test_pm_send_message_events(self) -> None:
self.verify_action(
lambda: self.send_personal_message(
self.example_user("cordelia"),
self.example_user("hamlet"),
"hola",
capture_on_commit_callbacks=False,
self.example_user("cordelia"), self.example_user("hamlet"), "hola"
),
)
@@ -513,16 +500,12 @@ class NormalActionsTest(BaseAction):
self.example_user("othello"),
]
self.verify_action(
lambda: self.send_huddle_message(
self.example_user("cordelia"), huddle, "hola", capture_on_commit_callbacks=False
),
lambda: self.send_huddle_message(self.example_user("cordelia"), huddle, "hola"),
)
def test_stream_send_message_events(self) -> None:
events = self.verify_action(
lambda: self.send_stream_message(
self.example_user("hamlet"), "Verona", "hello", capture_on_commit_callbacks=False
),
lambda: self.send_stream_message(self.example_user("hamlet"), "Verona", "hello"),
client_gravatar=False,
)
check_message("events[0]", events[0])
@@ -536,9 +519,7 @@ class NormalActionsTest(BaseAction):
)
events = self.verify_action(
lambda: self.send_stream_message(
self.example_user("hamlet"), "Verona", "hello", capture_on_commit_callbacks=False
),
lambda: self.send_stream_message(self.example_user("hamlet"), "Verona", "hello"),
client_gravatar=True,
)
check_message("events[0]", events[0])
@@ -749,16 +730,12 @@ class NormalActionsTest(BaseAction):
"hello 1",
)
self.verify_action(
lambda: self.send_stream_message(
sender, "Verona", "hello 2", capture_on_commit_callbacks=False
),
lambda: self.send_stream_message(sender, "Verona", "hello 2"),
state_change_expected=True,
)
def test_add_reaction(self) -> None:
message_id = self.send_stream_message(
self.example_user("hamlet"), "Verona", "hello", capture_on_commit_callbacks=False
)
message_id = self.send_stream_message(self.example_user("hamlet"), "Verona", "hello")
message = Message.objects.get(id=message_id)
events = self.verify_action(
lambda: do_add_reaction(self.user_profile, message, "tada", "1f389", "unicode_emoji"),
@@ -933,7 +910,7 @@ class NormalActionsTest(BaseAction):
num_events=7,
)
check_invites_changed("events[5]", events[5])
check_invites_changed("events[1]", events[1])
def test_typing_events(self) -> None:
events = self.verify_action(
@@ -1151,20 +1128,20 @@ class NormalActionsTest(BaseAction):
events = self.verify_action(lambda: self.register("test1@zulip.com", "test1"), num_events=5)
self.assert_length(events, 5)
check_realm_user_add("events[0]", events[0])
check_realm_user_add("events[1]", events[1])
new_user_profile = get_user_by_delivery_email("test1@zulip.com", self.user_profile.realm)
self.assertEqual(new_user_profile.delivery_email, "test1@zulip.com")
check_subscription_peer_add("events[3]", events[3])
check_subscription_peer_add("events[4]", events[4])
check_message("events[4]", events[4])
check_message("events[0]", events[0])
self.assertIn(
f'data-user-id="{new_user_profile.id}">test1_zulip.com</span> just signed up for Zulip',
events[4]["message"]["content"],
events[0]["message"]["content"],
)
check_user_group_add_members("events[1]", events[1])
check_user_group_add_members("events[2]", events[2])
check_user_group_add_members("events[3]", events[3])
def test_register_events_email_address_visibility(self) -> None:
realm_user_default = RealmUserDefault.objects.get(realm=self.user_profile.realm)
@@ -1177,20 +1154,20 @@ class NormalActionsTest(BaseAction):
events = self.verify_action(lambda: self.register("test1@zulip.com", "test1"), num_events=5)
self.assert_length(events, 5)
check_realm_user_add("events[0]", events[0])
check_realm_user_add("events[1]", events[1])
new_user_profile = get_user_by_delivery_email("test1@zulip.com", self.user_profile.realm)
self.assertEqual(new_user_profile.email, f"user{new_user_profile.id}@zulip.testserver")
check_subscription_peer_add("events[3]", events[3])
check_subscription_peer_add("events[4]", events[4])
check_message("events[4]", events[4])
check_message("events[0]", events[0])
self.assertIn(
f'data-user-id="{new_user_profile.id}">test1_zulip.com</span> just signed up for Zulip',
events[4]["message"]["content"],
events[0]["message"]["content"],
)
check_user_group_add_members("events[1]", events[1])
check_user_group_add_members("events[2]", events[2])
check_user_group_add_members("events[3]", events[3])
def test_alert_words_events(self) -> None:
events = self.verify_action(lambda: do_add_alert_words(self.user_profile, ["alert_word"]))
@@ -2428,13 +2405,7 @@ class NormalActionsTest(BaseAction):
assert uri is not None
body = f"First message ...[zulip.txt](http://{hamlet.realm.host}" + uri + ")"
events = self.verify_action(
lambda: self.send_stream_message(
self.example_user("hamlet"),
"Denmark",
body,
"test",
capture_on_commit_callbacks=False,
),
lambda: self.send_stream_message(self.example_user("hamlet"), "Denmark", body, "test"),
num_events=2,
)