Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise exception if both cms.celery and lms.celery are imported #25825

Closed
wants to merge 2 commits into from

Conversation

timmc-edx
Copy link
Contributor

In #25822 we protect against the case where any cms.** module is
imported by the running LMS process, causing cms.celery to be imported
and a second celery to be instantiated (leading to tasks being registered
to the wrong one and effectively lost).

This commit protects against the more restricted case of cms.celery or
lms.celery being imported explicitly, rather than implicitly by their
respective root __init__.py.

In #25822 we protect against the case where *any* `cms.**` module is
imported by the running LMS process, causing cms.celery to be imported
and a second celery to be instantiated (leading to tasks being registered
to the wrong one and effectively lost).

This commit protects against the more restricted case of `cms.celery` or
`lms.celery` being imported explicitly, rather than implicitly by their
respective root `__init__.py`.
from openedx.core.lib.celery.routers import AlternateEnvironmentRouter

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cms.envs.production')

# Prevent instantiation of both CMS and LMS celery.
# See assert_celery_uninstantiated for more details.
assert_celery_uninstantiated('cms')
Copy link
Contributor

Choose a reason for hiding this comment

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

In which process would this code be run? In the CMS process or the CMS worker process? I'm trying to determine:

  1. which process would get killed.
  2. does the mutex need to be updated at a later point.

Copy link
Contributor

Choose a reason for hiding this comment

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

This would break if LMS or LMS Worker processes tried to import cms.celery directly.

It will not break if CMS or CMS Worker processes imported cms.celery multiple times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe it would be run in both. cms/__init__.py imports cms.celery, so if any module under cms is loaded, this code runs. However, Feanil's change means that at least if the LMS process loads CMS code, this doesn't get loaded automatically. There's still the possibility that something imports it more directly, either now or in the future, and only in that case should this kill the process.

The assertion function should only get called once per process under normal conditions -- the cms.celery module is loaded for the first time, and the SINGLETON_VARIANT changes from None to 'cms'. If the module is imported again, there's no additional call, since the module is already loaded.

The only time the function would be called multiple times is if both lms.celery and cms.celery are imported, which we very much want to avoid (and don't believe currently happens, after #25822).

@cpennington
Copy link
Contributor

Studio imports stuff from LMS. I'm not sure if that stuff includes things that import celery. I'm sure you have, but to ask the obvious question: does studio start w/ this assertion?

@edx-status-bot
Copy link

Your PR has finished running tests. The following contexts failed:

  • jenkins/python

@timmc-edx
Copy link
Contributor Author

At least one test doesn't like this, but that was expected. :-/

@timmc-edx
Copy link
Contributor Author

@cpennington I haven't verified with devstack yet, but the results of a code grep were promising.

feanil referenced this pull request Dec 9, 2020
This should no longer be necessary now that we have found a root cause
fix for the issue. This was removed because it was causing the case
of celery tasks not getting registered to happen more often.

Undoing https://github.com/edx/edx-platform/pull/25787

Actual Fixes:
- https://github.com/edx/edx-platform/pull/25822
- https://github.com/edx/edx-platform/pull/25825
@timmc-edx
Copy link
Contributor Author

Yes, LMS and Studio run fine locally.

from openedx.core.lib.celery.routers import AlternateEnvironmentRouter

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lms.envs.production')

# Prevent instantiation of both CMS and LMS celery.
# See assert_celery_uninstantiated for more details.
assert_celery_uninstantiated('lms')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This ends up breaking tests, which load both cms and lms files and also don't define a SERVICE_VARIANT environment variable, thus loading both cms.celery and lms.celery. There are several possible options, but none totally straightforward, I think.

@feanil
Copy link
Contributor

feanil commented Dec 10, 2020

@feanil feanil closed this Dec 10, 2020
@feanil feanil deleted the timmc/celery-mollyguard branch December 10, 2020 16:19
feanil referenced this pull request Dec 10, 2020
This should no longer be necessary now that we have found a root cause
fix for the issue. This was removed because it was causing the case
of celery tasks not getting registered to happen more often.

Undoing https://github.com/edx/edx-platform/pull/25787

Actual Fixes:
- https://github.com/edx/edx-platform/pull/25822
- https://github.com/edx/edx-platform/pull/25825
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants