# Buggy code
def save_user_session_membership(sender, **kwargs):
    session = kwargs.get("instance", None)
    if pkg_resources.get_distribution("channels").version >= "2":
        # If you get into this code block, it means we upgraded channels, but
        # didn't make the settings.SESSIONS_PER_USER feature work
        raise RuntimeError(
            "save_user_session_membership must be updated for channels>=2: "
            "http://channels.readthedocs.io/en/latest/one-to-two.html#requirements"
        )
    if "runworker" in sys.argv:
        # don't track user session membership for websocket per-channel sessions
        return
    if not session:
        return
    user_id = session.get_decoded().get(SESSION_KEY, None)
    if not user_id:
        return
    if UserSessionMembership.objects.filter(user=user_id, session=session).exists():
        return
    UserSessionMembership(
        user_id=user_id, session=session, created=timezone.now()
    ).save()
    expired = UserSessionMembership.get_memberships_over_limit(user_id)
    for membership in expired:
        Session.objects.filter(session_key__in=[membership.session_id]).delete()
        membership.delete()
    if len(expired):
        consumers.emit_channel_notification(
            "control-limit_reached_{}".format(user_id),
            dict(group_name="control", reason="limit_reached"),
        )


# Traceback (psycopg2.IntegrityError)
awx_1        | 2019-07-16 21:07:30,594 ERROR    django.request Internal Server Error: /
awx_1        | Traceback (most recent call last):
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/backends/base/base.py", line 240, in _commit
awx_1        |     return self.connection.commit()
awx_1        | psycopg2.IntegrityError: insert or update on table "main_usersessionmembership" violates foreign key constraint "main_usersessionmembership_user_id_fe163c98_fk_auth_user_id"
awx_1        | DETAIL:  Key (user_id)=(2) is not present in table "auth_user".
awx_1        |
awx_1        |
awx_1        | The above exception was the direct cause of the following exception:
awx_1        |
awx_1        | Traceback (most recent call last):
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
awx_1        |     response = get_response(request)
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/utils/deprecation.py", line 96, in __call__
awx_1        |     response = self.process_response(request, response)
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/contrib/sessions/middleware.py", line 58, in process_response
awx_1        |     request.session.save()
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 87, in save
awx_1        |     obj.save(force_insert=must_create, force_update=not must_create, using=using)
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/transaction.py", line 240, in __exit__
awx_1        |     connection.commit()
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/backends/base/base.py", line 262, in commit
awx_1        |     self._commit()
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/backends/base/base.py", line 240, in _commit
awx_1        |     return self.connection.commit()
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
awx_1        |     raise dj_exc_value.with_traceback(traceback) from exc_value
awx_1        |   File "/venv/awx/lib64/python3.6/site-packages/django/db/backends/base/base.py", line 240, in _commit
awx_1        |     return self.connection.commit()
awx_1        | django.db.utils.IntegrityError: insert or update on table "main_usersessionmembership" violates foreign key constraint "main_usersessionmembership_user_id_fe163c98_fk_auth_user_id"
awx_1        | DETAIL:  Key (user_id)=(2) is not present in table "auth_user".

# Fixed code
def save_user_session_membership(sender, **kwargs):
    session = kwargs.get("instance", None)
    if pkg_resources.get_distribution("channels").version >= "2":
        # If you get into this code block, it means we upgraded channels, but
        # didn't make the settings.SESSIONS_PER_USER feature work
        raise RuntimeError(
            "save_user_session_membership must be updated for channels>=2: "
            "http://channels.readthedocs.io/en/latest/one-to-two.html#requirements"
        )
    if "runworker" in sys.argv:
        # don't track user session membership for websocket per-channel sessions
        return
    if not session:
        return
    user_id = session.get_decoded().get(SESSION_KEY, None)
    if not user_id:
        return
    if UserSessionMembership.objects.filter(user=user_id, session=session).exists():
        return
    # check if user_id from session has an id match in User before saving
    if User.objects.filter(id=int(user_id)).exists():
        UserSessionMembership(
            user_id=user_id, session=session, created=timezone.now()
        ).save()
        expired = UserSessionMembership.get_memberships_over_limit(user_id)
        for membership in expired:
            Session.objects.filter(session_key__in=[membership.session_id]).delete()
            membership.delete()
        if len(expired):
            consumers.emit_channel_notification(
                "control-limit_reached_{}".format(user_id),
                dict(group_name="control", reason="limit_reached"),
            )