Skip to content

Conversation

@mdumandag
Copy link
Contributor

@mdumandag mdumandag commented Mar 10, 2021

As of now, during the authentication process, we, more or less, do the
following:

  • Send an authentication request
  • Put a future that will be resolved after the authentication request completes
    to the pending connections that performs client-side authentication logic
    (ConnectionManager#on_auth)
  • Return the future

The problem is that, through unlucky timing, we might perform the
authentication logic before putting the future to the pending connections
map. Such as,

  • Clients initiates get_or_connect in the main thread during startup
  • We send the authentication request in the main thread
  • Before we return the invocation future, and add a callback to it,
    Python schedules the reactor thread, we write the request to wire,
    and get back the response.
  • Python schedules the main thread again, it is now trying to add
    a callback to a completed future. Since it is completed, it executes
    the authentication logic immediately. One of the steps of the client
    side authentication logic is to remove the connection from the pending
    connections map. Since the future is not put into the map yet, nothing
    is removed.
  • We then add this future to the pending connections map, but since
    it is already completed, no one is going to remove it from the
    pending connections map.
  • During the shutdown, we see an unexpected entry in the pending
    connections map and fail.

To solve this, we put a future directly into the pending connections
and perform the logic afterward.

Closes #378

As of now, during the authentication process, we, more or less, do the
following:

- Send an authentication request
- Put a future that will be resolved after the authentication request completes
to the pending connections that performs client-side authentication logic
(ConnectionManager#on_auth)
- Return the future

The problem is that, through unlucky timing, we might perform the
authentication logic before putting the future to the pending connections
map. Such as,

- Clients initiates get_or_connect in the main thread during startup
- We send the authentication request in the main thread
- Before we return the invocation future, and add a callback to it,
Python schedules the reactor thread, we write the request to wire,
and get back the response.
- Python schedules the main thread again, it is now trying to add
a callback to a completed future. Since it is completed, it executes
the authentication logic immediately. One of the steps of the client
side authentication logic is to remove the connection from the pending
connections map. Since the future is not put into the map yet, nothing
is removed.
- We then add this future to the pending connections map, but since
it is already completed, no one is going to remove it from the
pending connections map.
- During the shutdown, we see an unexpected entry in the pending
connections map and fail.

To solve this, we put a future directly into the pending connections
and perform the logic afterward.
@srknzl
Copy link
Contributor

srknzl commented Mar 26, 2021

Python schedules the reactor thread

What is a reactor thread

@srknzl
Copy link
Contributor

srknzl commented Mar 26, 2021

This is so interesting :)

@srknzl
Copy link
Contributor

srknzl commented Mar 26, 2021

To solve this, we put a future directly into the pending connections
and perform the logic afterward.

yeah this is what I thought as well immediately after reading the problem

else:
e = response.exception()
# This will set the exception for the pending connection future
connection.close("Failed to authenticate connection", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this close calls cause self._authenticate(connection) call to raise exception. Is this right?

@mdumandag
Copy link
Contributor Author

Closing this in favor of #388

@mdumandag mdumandag closed this Apr 2, 2021
@mdumandag mdumandag deleted the auth-fix branch April 2, 2021 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tests.proxy.cp.fenced_lock_test.FencedLockTest.test_lock_after_client_shutdown

2 participants