Merge pull request #2063 from edx/feature/rocha/lets-use-celery
Add Celery configuration to LMS and CMS
This commit is contained in:
@@ -28,6 +28,47 @@ EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
|
||||
|
||||
###################################### CELERY ################################
|
||||
|
||||
# Don't use a connection pool, since connections are dropped by ELB.
|
||||
BROKER_POOL_LIMIT = 0
|
||||
BROKER_CONNECTION_TIMEOUT = 1
|
||||
|
||||
# For the Result Store, use the django cache named 'celery'
|
||||
CELERY_RESULT_BACKEND = 'cache'
|
||||
CELERY_CACHE_BACKEND = 'celery'
|
||||
|
||||
# When the broker is behind an ELB, use a heartbeat to refresh the
|
||||
# connection and to detect if it has been dropped.
|
||||
BROKER_HEARTBEAT = 10.0
|
||||
BROKER_HEARTBEAT_CHECKRATE = 2
|
||||
|
||||
# Each worker should only fetch one message at a time
|
||||
CELERYD_PREFETCH_MULTIPLIER = 1
|
||||
|
||||
# Skip djcelery migrations, since we don't use the database as the broker
|
||||
SOUTH_MIGRATION_MODULES = {
|
||||
'djcelery': 'ignore',
|
||||
}
|
||||
|
||||
# Rename the exchange and queues for each variant
|
||||
|
||||
QUEUE_VARIANT = CONFIG_PREFIX.lower()
|
||||
|
||||
CELERY_DEFAULT_EXCHANGE = 'edx.{0}core'.format(QUEUE_VARIANT)
|
||||
|
||||
HIGH_PRIORITY_QUEUE = 'edx.{0}core.high'.format(QUEUE_VARIANT)
|
||||
DEFAULT_PRIORITY_QUEUE = 'edx.{0}core.default'.format(QUEUE_VARIANT)
|
||||
LOW_PRIORITY_QUEUE = 'edx.{0}core.low'.format(QUEUE_VARIANT)
|
||||
|
||||
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
|
||||
|
||||
CELERY_QUEUES = {
|
||||
HIGH_PRIORITY_QUEUE: {},
|
||||
LOW_PRIORITY_QUEUE: {},
|
||||
DEFAULT_PRIORITY_QUEUE: {}
|
||||
}
|
||||
|
||||
############# NON-SECURE ENV CONFIG ##############################
|
||||
# Things like server locations, ports, etc.
|
||||
with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
|
||||
@@ -78,3 +119,14 @@ CONTENTSTORE = AUTH_TOKENS['CONTENTSTORE']
|
||||
|
||||
# Datadog for events!
|
||||
DATADOG_API = AUTH_TOKENS.get("DATADOG_API")
|
||||
|
||||
# Celery Broker
|
||||
CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "")
|
||||
CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "")
|
||||
CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "")
|
||||
CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "")
|
||||
|
||||
BROKER_URL = "{0}://{1}:{2}@{3}".format(CELERY_BROKER_TRANSPORT,
|
||||
CELERY_BROKER_USER,
|
||||
CELERY_BROKER_PASSWORD,
|
||||
CELERY_BROKER_HOSTNAME)
|
||||
|
||||
@@ -34,6 +34,9 @@ MITX_FEATURES = {
|
||||
'STAFF_EMAIL': '', # email address for staff (eg to request course creation)
|
||||
'STUDIO_NPS_SURVEY': True,
|
||||
'SEGMENT_IO': True,
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
'ENABLE_SERVICE_STATUS': False,
|
||||
}
|
||||
ENABLE_JASMINE = False
|
||||
|
||||
@@ -240,6 +243,51 @@ STATICFILES_IGNORE_PATTERNS = (
|
||||
|
||||
PIPELINE_YUI_BINARY = 'yui-compressor'
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
# Message configuration
|
||||
|
||||
CELERY_TASK_SERIALIZER = 'json'
|
||||
CELERY_RESULT_SERIALIZER = 'json'
|
||||
|
||||
CELERY_MESSAGE_COMPRESSION = 'gzip'
|
||||
|
||||
# Results configuration
|
||||
|
||||
CELERY_IGNORE_RESULT = False
|
||||
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True
|
||||
|
||||
# Events configuration
|
||||
|
||||
CELERY_TRACK_STARTED = True
|
||||
|
||||
CELERY_SEND_EVENTS = True
|
||||
CELERY_SEND_TASK_SENT_EVENT = True
|
||||
|
||||
# Exchange configuration
|
||||
|
||||
CELERY_DEFAULT_EXCHANGE = 'edx.core'
|
||||
CELERY_DEFAULT_EXCHANGE_TYPE = 'direct'
|
||||
|
||||
# Queues configuration
|
||||
|
||||
HIGH_PRIORITY_QUEUE = 'edx.core.high'
|
||||
DEFAULT_PRIORITY_QUEUE = 'edx.core.default'
|
||||
LOW_PRIORITY_QUEUE = 'edx.core.low'
|
||||
|
||||
CELERY_QUEUE_HA_POLICY = 'all'
|
||||
|
||||
CELERY_CREATE_MISSING_QUEUES = True
|
||||
|
||||
CELERY_DEFAULT_QUEUE = DEFAULT_PRIORITY_QUEUE
|
||||
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
|
||||
|
||||
CELERY_QUEUES = {
|
||||
HIGH_PRIORITY_QUEUE: {},
|
||||
LOW_PRIORITY_QUEUE: {},
|
||||
DEFAULT_PRIORITY_QUEUE: {}
|
||||
}
|
||||
|
||||
############################ APPS #####################################
|
||||
|
||||
INSTALLED_APPS = (
|
||||
@@ -249,8 +297,12 @@ INSTALLED_APPS = (
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'djcelery',
|
||||
'south',
|
||||
|
||||
# Monitor the status of services
|
||||
'service_status',
|
||||
|
||||
# For CMS
|
||||
'contentstore',
|
||||
'auth',
|
||||
|
||||
@@ -116,6 +116,11 @@ SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
PIPELINE_SASS_ARGUMENTS = '--debug-info --require {proj_dir}/static/sass/bourbon/lib/bourbon.rb'.format(proj_dir=PROJECT_ROOT)
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
# By default don't use a worker, execute tasks as if they were local functions
|
||||
CELERY_ALWAYS_EAGER = True
|
||||
|
||||
################################ DEBUG TOOLBAR #################################
|
||||
INSTALLED_APPS += ('debug_toolbar', 'debug_toolbar_mongo')
|
||||
MIDDLEWARE_CLASSES += ('django_comment_client.utils.QueryCountDebugMiddleware',
|
||||
@@ -151,5 +156,8 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True
|
||||
# disable NPS survey in dev mode
|
||||
MITX_FEATURES['STUDIO_NPS_SURVEY'] = False
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
# segment-io key for dev
|
||||
SEGMENT_IO_KEY = 'mty8edrrsg'
|
||||
|
||||
35
cms/envs/dev_with_worker.py
Normal file
35
cms/envs/dev_with_worker.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
This config file follows the dev enviroment, but adds the
|
||||
requirement of a celery worker running in the background to process
|
||||
celery tasks.
|
||||
|
||||
The worker can be executed using:
|
||||
|
||||
django_admin.py celery worker
|
||||
"""
|
||||
|
||||
from dev import *
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
# Requires a separate celery worker
|
||||
|
||||
CELERY_ALWAYS_EAGER = False
|
||||
|
||||
# Use django db as the broker and result store
|
||||
|
||||
BROKER_URL = 'django://'
|
||||
INSTALLED_APPS += ('djcelery.transport', )
|
||||
CELERY_RESULT_BACKEND = 'database'
|
||||
DJKOMBU_POLLING_INTERVAL = 1.0
|
||||
|
||||
# Disable transaction management because we are using a worker. Views
|
||||
# that request a task and wait for the result will deadlock otherwise.
|
||||
|
||||
MIDDLEWARE_CLASSES = tuple(
|
||||
c for c in MIDDLEWARE_CLASSES
|
||||
if c != 'django.middleware.transaction.TransactionMiddleware')
|
||||
|
||||
# Note: other alternatives for disabling transactions don't work in 1.4
|
||||
# https://code.djangoproject.com/ticket/2304
|
||||
# https://code.djangoproject.com/ticket/16039
|
||||
@@ -108,6 +108,12 @@ CACHES = {
|
||||
}
|
||||
}
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
CELERY_ALWAYS_EAGER = True
|
||||
CELERY_RESULT_BACKEND = 'cache'
|
||||
BROKER_TRANSPORT = 'memory'
|
||||
|
||||
################### Make tests faster
|
||||
#http://slacy.com/blog/2012/04/make-your-tests-faster-in-django-1-4/
|
||||
PASSWORD_HASHERS = (
|
||||
@@ -121,3 +127,4 @@ SEGMENT_IO_KEY = '***REMOVED***'
|
||||
# disable NPS survey in test mode
|
||||
MITX_FEATURES['STUDIO_NPS_SURVEY'] = False
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
@@ -135,6 +135,12 @@ if settings.ENABLE_JASMINE:
|
||||
# # Jasmine
|
||||
urlpatterns = urlpatterns + (url(r'^_jasmine/', include('django_jasmine.urls')),)
|
||||
|
||||
|
||||
if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
|
||||
urlpatterns += (
|
||||
url(r'^status/', include('service_status.urls')),
|
||||
)
|
||||
|
||||
urlpatterns = patterns(*urlpatterns)
|
||||
|
||||
# Custom error pages
|
||||
|
||||
3
common/djangoapps/service_status/__init__.py
Normal file
3
common/djangoapps/service_status/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Stub for a Django app to report the status of various services
|
||||
"""
|
||||
25
common/djangoapps/service_status/tasks.py
Normal file
25
common/djangoapps/service_status/tasks.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Django Celery tasks for service status app
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
from dogapi import dog_stats_api
|
||||
|
||||
from djcelery import celery
|
||||
|
||||
|
||||
@celery.task
|
||||
@dog_stats_api.timed('status.service.celery.pong')
|
||||
def delayed_ping(value, delay):
|
||||
"""A simple tasks that replies to a message after a especified amount
|
||||
of seconds.
|
||||
"""
|
||||
if value == 'ping':
|
||||
result = 'pong'
|
||||
else:
|
||||
result = 'got: {0}'.format(value)
|
||||
|
||||
time.sleep(delay)
|
||||
|
||||
return result
|
||||
47
common/djangoapps/service_status/test.py
Normal file
47
common/djangoapps/service_status/test.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""Test for async task service status"""
|
||||
|
||||
from django.utils import unittest
|
||||
from django.test.client import Client
|
||||
from django.core.urlresolvers import reverse
|
||||
import json
|
||||
|
||||
|
||||
class CeleryConfigTest(unittest.TestCase):
|
||||
"""
|
||||
Test that we can get a response from Celery
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Create a django test client
|
||||
"""
|
||||
self.client = Client()
|
||||
self.ping_url = reverse('status.service.celery.ping')
|
||||
|
||||
def test_ping(self):
|
||||
"""
|
||||
Try to ping celery.
|
||||
"""
|
||||
|
||||
# Access the service status page, which starts a delayed
|
||||
# asynchronous task
|
||||
response = self.client.get(self.ping_url)
|
||||
|
||||
# HTTP response should be successful
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Expect to get a JSON-serialized dict with
|
||||
# task and time information
|
||||
result_dict = json.loads(response.content)
|
||||
|
||||
# Was it successful?
|
||||
self.assertTrue(result_dict['success'])
|
||||
|
||||
# We should get a "pong" message back
|
||||
self.assertEqual(result_dict['value'], "pong")
|
||||
|
||||
# We don't know the other dict values exactly,
|
||||
# but we can assert that they take the right form
|
||||
self.assertTrue(isinstance(result_dict['task_id'], unicode))
|
||||
self.assertTrue(isinstance(result_dict['time'], float))
|
||||
self.assertTrue(result_dict['time'] > 0.0)
|
||||
15
common/djangoapps/service_status/urls.py
Normal file
15
common/djangoapps/service_status/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Django URLs for service status app
|
||||
"""
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^$', 'service_status.views.index', name='status.service.index'),
|
||||
url(r'^celery/$', 'service_status.views.celery_status',
|
||||
name='status.service.celery.status'),
|
||||
url(r'^celery/ping/$', 'service_status.views.celery_ping',
|
||||
name='status.service.celery.ping'),
|
||||
)
|
||||
59
common/djangoapps/service_status/views.py
Normal file
59
common/djangoapps/service_status/views.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
Django Views for service status app
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
from django.http import HttpResponse
|
||||
|
||||
from dogapi import dog_stats_api
|
||||
|
||||
from service_status import tasks
|
||||
from djcelery import celery
|
||||
from celery.exceptions import TimeoutError
|
||||
|
||||
|
||||
def index(_):
|
||||
"""
|
||||
An empty view
|
||||
"""
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
@dog_stats_api.timed('status.service.celery.status')
|
||||
def celery_status(_):
|
||||
"""
|
||||
A view that returns Celery stats
|
||||
"""
|
||||
stats = celery.control.inspect().stats() or {}
|
||||
return HttpResponse(json.dumps(stats, indent=4),
|
||||
mimetype="application/json")
|
||||
|
||||
|
||||
@dog_stats_api.timed('status.service.celery.ping')
|
||||
def celery_ping(_):
|
||||
"""
|
||||
A Simple view that checks if Celery can process a simple task
|
||||
"""
|
||||
start = time.time()
|
||||
result = tasks.delayed_ping.apply_async(('ping', 0.1))
|
||||
task_id = result.id
|
||||
|
||||
# Wait until we get the result
|
||||
try:
|
||||
value = result.get(timeout=4.0)
|
||||
success = True
|
||||
except TimeoutError:
|
||||
value = None
|
||||
success = False
|
||||
|
||||
output = {
|
||||
'success': success,
|
||||
'task_id': task_id,
|
||||
'value': value,
|
||||
'time': time.time() - start,
|
||||
}
|
||||
|
||||
return HttpResponse(json.dumps(output, indent=4),
|
||||
mimetype="application/json")
|
||||
@@ -26,7 +26,8 @@ if SERVICE_VARIANT:
|
||||
CONFIG_PREFIX = SERVICE_VARIANT + "."
|
||||
|
||||
|
||||
################### ALWAYS THE SAME ################################
|
||||
################################ ALWAYS THE SAME ##############################
|
||||
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = False
|
||||
|
||||
@@ -45,7 +46,48 @@ MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
|
||||
# for other warnings.
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
|
||||
################# NON-SECURE ENV CONFIG ##############################
|
||||
###################################### CELERY ################################
|
||||
|
||||
# Don't use a connection pool, since connections are dropped by ELB.
|
||||
BROKER_POOL_LIMIT = 0
|
||||
BROKER_CONNECTION_TIMEOUT = 1
|
||||
|
||||
# For the Result Store, use the django cache named 'celery'
|
||||
CELERY_RESULT_BACKEND = 'cache'
|
||||
CELERY_CACHE_BACKEND = 'celery'
|
||||
|
||||
# When the broker is behind an ELB, use a heartbeat to refresh the
|
||||
# connection and to detect if it has been dropped.
|
||||
BROKER_HEARTBEAT = 10.0
|
||||
BROKER_HEARTBEAT_CHECKRATE = 2
|
||||
|
||||
# Each worker should only fetch one message at a time
|
||||
CELERYD_PREFETCH_MULTIPLIER = 1
|
||||
|
||||
# Skip djcelery migrations, since we don't use the database as the broker
|
||||
SOUTH_MIGRATION_MODULES = {
|
||||
'djcelery': 'ignore',
|
||||
}
|
||||
|
||||
# Rename the exchange and queues for each variant
|
||||
|
||||
QUEUE_VARIANT = CONFIG_PREFIX.lower()
|
||||
|
||||
CELERY_DEFAULT_EXCHANGE = 'edx.{0}core'.format(QUEUE_VARIANT)
|
||||
|
||||
HIGH_PRIORITY_QUEUE = 'edx.{0}core.high'.format(QUEUE_VARIANT)
|
||||
DEFAULT_PRIORITY_QUEUE = 'edx.{0}core.default'.format(QUEUE_VARIANT)
|
||||
LOW_PRIORITY_QUEUE = 'edx.{0}core.low'.format(QUEUE_VARIANT)
|
||||
|
||||
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
|
||||
|
||||
CELERY_QUEUES = {
|
||||
HIGH_PRIORITY_QUEUE: {},
|
||||
LOW_PRIORITY_QUEUE: {},
|
||||
DEFAULT_PRIORITY_QUEUE: {}
|
||||
}
|
||||
|
||||
########################## NON-SECURE ENV CONFIG ##############################
|
||||
# Things like server locations, ports, etc.
|
||||
|
||||
with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
|
||||
@@ -104,6 +146,7 @@ COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", [])
|
||||
|
||||
############################## SECURE AUTH ITEMS ###############
|
||||
# Secret things: passwords, access keys, etc.
|
||||
|
||||
with open(ENV_ROOT / CONFIG_PREFIX + "auth.json") as auth_file:
|
||||
AUTH_TOKENS = json.load(auth_file)
|
||||
|
||||
@@ -122,7 +165,8 @@ XQUEUE_INTERFACE = AUTH_TOKENS['XQUEUE_INTERFACE']
|
||||
MODULESTORE = AUTH_TOKENS.get('MODULESTORE', MODULESTORE)
|
||||
CONTENTSTORE = AUTH_TOKENS.get('CONTENTSTORE', CONTENTSTORE)
|
||||
|
||||
OPEN_ENDED_GRADING_INTERFACE = AUTH_TOKENS.get('OPEN_ENDED_GRADING_INTERFACE', OPEN_ENDED_GRADING_INTERFACE)
|
||||
OPEN_ENDED_GRADING_INTERFACE = AUTH_TOKENS.get('OPEN_ENDED_GRADING_INTERFACE',
|
||||
OPEN_ENDED_GRADING_INTERFACE)
|
||||
|
||||
PEARSON_TEST_USER = "pearsontest"
|
||||
PEARSON_TEST_PASSWORD = AUTH_TOKENS.get("PEARSON_TEST_PASSWORD")
|
||||
@@ -137,5 +181,17 @@ DATADOG_API = AUTH_TOKENS.get("DATADOG_API")
|
||||
ANALYTICS_SERVER_URL = ENV_TOKENS.get("ANALYTICS_SERVER_URL")
|
||||
ANALYTICS_API_KEY = AUTH_TOKENS.get("ANALYTICS_API_KEY", "")
|
||||
|
||||
# Zendesk
|
||||
ZENDESK_USER = AUTH_TOKENS.get("ZENDESK_USER")
|
||||
ZENDESK_API_KEY = AUTH_TOKENS.get("ZENDESK_API_KEY")
|
||||
|
||||
# Celery Broker
|
||||
CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "")
|
||||
CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "")
|
||||
CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "")
|
||||
CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "")
|
||||
|
||||
BROKER_URL = "{0}://{1}:{2}@{3}".format(CELERY_BROKER_TRANSPORT,
|
||||
CELERY_BROKER_USER,
|
||||
CELERY_BROKER_PASSWORD,
|
||||
CELERY_BROKER_HOSTNAME)
|
||||
|
||||
@@ -101,6 +101,9 @@ MITX_FEATURES = {
|
||||
# Turn on a page that lets staff enter Python code to be run in the
|
||||
# sandbox, for testing whether it's enabled properly.
|
||||
'ENABLE_DEBUG_RUN_PYTHON': False,
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
'ENABLE_SERVICE_STATUS': False,
|
||||
}
|
||||
|
||||
# Used for A/B testing
|
||||
@@ -582,7 +585,52 @@ PIPELINE_YUI_BINARY = 'yui-compressor'
|
||||
# Setting that will only affect the MITx version of django-pipeline until our changes are merged upstream
|
||||
PIPELINE_COMPILE_INPLACE = True
|
||||
|
||||
################################### APPS #######################################
|
||||
################################# CELERY ######################################
|
||||
|
||||
# Message configuration
|
||||
|
||||
CELERY_TASK_SERIALIZER = 'json'
|
||||
CELERY_RESULT_SERIALIZER = 'json'
|
||||
|
||||
CELERY_MESSAGE_COMPRESSION = 'gzip'
|
||||
|
||||
# Results configuration
|
||||
|
||||
CELERY_IGNORE_RESULT = False
|
||||
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True
|
||||
|
||||
# Events configuration
|
||||
|
||||
CELERY_TRACK_STARTED = True
|
||||
|
||||
CELERY_SEND_EVENTS = True
|
||||
CELERY_SEND_TASK_SENT_EVENT = True
|
||||
|
||||
# Exchange configuration
|
||||
|
||||
CELERY_DEFAULT_EXCHANGE = 'edx.core'
|
||||
CELERY_DEFAULT_EXCHANGE_TYPE = 'direct'
|
||||
|
||||
# Queues configuration
|
||||
|
||||
HIGH_PRIORITY_QUEUE = 'edx.core.high'
|
||||
DEFAULT_PRIORITY_QUEUE = 'edx.core.default'
|
||||
LOW_PRIORITY_QUEUE = 'edx.core.low'
|
||||
|
||||
CELERY_QUEUE_HA_POLICY = 'all'
|
||||
|
||||
CELERY_CREATE_MISSING_QUEUES = True
|
||||
|
||||
CELERY_DEFAULT_QUEUE = DEFAULT_PRIORITY_QUEUE
|
||||
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
|
||||
|
||||
CELERY_QUEUES = {
|
||||
HIGH_PRIORITY_QUEUE: {},
|
||||
LOW_PRIORITY_QUEUE: {},
|
||||
DEFAULT_PRIORITY_QUEUE: {}
|
||||
}
|
||||
|
||||
################################### APPS ######################################
|
||||
INSTALLED_APPS = (
|
||||
# Standard ones that are always installed...
|
||||
'django.contrib.auth',
|
||||
@@ -591,8 +639,12 @@ INSTALLED_APPS = (
|
||||
'django.contrib.messages',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'djcelery',
|
||||
'south',
|
||||
|
||||
# Monitor the status of services
|
||||
'service_status',
|
||||
|
||||
# For asset pipelining
|
||||
'pipeline',
|
||||
'staticfiles',
|
||||
@@ -639,4 +691,3 @@ INSTALLED_APPS = (
|
||||
# Student notes
|
||||
'notes',
|
||||
)
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@ MITX_FEATURES['FORCE_UNIVERSITY_DOMAIN'] = None # show all university courses i
|
||||
MITX_FEATURES['ENABLE_MANUAL_GIT_RELOAD'] = True
|
||||
MITX_FEATURES['ENABLE_PSYCHOMETRICS'] = False # real-time psychometrics (eg item response theory analysis in instructor dashboard)
|
||||
MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True
|
||||
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
WIKI_ENABLED = True
|
||||
|
||||
@@ -143,7 +142,7 @@ if os.path.isdir(DATA_DIR):
|
||||
|
||||
MITX_VERSION_STRING = os.popen('cd %s; git describe' % REPO_ROOT).read().strip()
|
||||
|
||||
################################# Open ended grading config #####################
|
||||
############################ Open ended grading config #####################
|
||||
|
||||
OPEN_ENDED_GRADING_INTERFACE = {
|
||||
'url' : 'http://127.0.0.1:3033/',
|
||||
@@ -154,7 +153,7 @@ OPEN_ENDED_GRADING_INTERFACE = {
|
||||
'grading_controller' : 'grading_controller'
|
||||
}
|
||||
|
||||
################################ LMS Migration #################################
|
||||
############################## LMS Migration ##################################
|
||||
MITX_FEATURES['ENABLE_LMS_MIGRATION'] = True
|
||||
MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = False # require that user be in the staff_* group to be able to enroll
|
||||
MITX_FEATURES['USE_XQA_SERVER'] = 'http://xqa:server@content-qa.mitx.mit.edu/xqa'
|
||||
@@ -164,6 +163,7 @@ INSTALLED_APPS += ('lms_migration',)
|
||||
LMS_MIGRATION_ALLOWED_IPS = ['127.0.0.1']
|
||||
|
||||
################################ OpenID Auth #################################
|
||||
|
||||
MITX_FEATURES['AUTH_USE_OPENID'] = True
|
||||
MITX_FEATURES['AUTH_USE_OPENID_PROVIDER'] = True
|
||||
MITX_FEATURES['BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'] = True
|
||||
@@ -173,16 +173,22 @@ INSTALLED_APPS += ('django_openid_auth',)
|
||||
|
||||
OPENID_CREATE_USERS = False
|
||||
OPENID_UPDATE_DETAILS_FROM_SREG = True
|
||||
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/id' # TODO: accept more endpoints
|
||||
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/id' # TODO: accept more endpoints
|
||||
OPENID_USE_AS_ADMIN_LOGIN = False
|
||||
|
||||
OPENID_PROVIDER_TRUSTED_ROOTS = ['*']
|
||||
|
||||
################################ MIT Certificates SSL Auth #################################
|
||||
######################## MIT Certificates SSL Auth ############################
|
||||
|
||||
MITX_FEATURES['AUTH_USE_MIT_CERTIFICATES'] = True
|
||||
|
||||
################################ DEBUG TOOLBAR #################################
|
||||
################################# CELERY ######################################
|
||||
|
||||
# By default don't use a worker, execute tasks as if they were local functions
|
||||
CELERY_ALWAYS_EAGER = True
|
||||
|
||||
################################ DEBUG TOOLBAR ################################
|
||||
|
||||
INSTALLED_APPS += ('debug_toolbar',)
|
||||
MIDDLEWARE_CLASSES += ('django_comment_client.utils.QueryCountDebugMiddleware',
|
||||
'debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||
@@ -208,7 +214,9 @@ DEBUG_TOOLBAR_PANELS = (
|
||||
DEBUG_TOOLBAR_CONFIG = {
|
||||
'INTERCEPT_REDIRECTS': False
|
||||
}
|
||||
############################ FILE UPLOADS (for discussion forums) #############################
|
||||
|
||||
#################### FILE UPLOADS (for discussion forums) #####################
|
||||
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
MEDIA_ROOT = ENV_ROOT / "uploads"
|
||||
MEDIA_URL = "/static/uploads/"
|
||||
|
||||
35
lms/envs/dev_with_worker.py
Normal file
35
lms/envs/dev_with_worker.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
This config file follows the dev enviroment, but adds the
|
||||
requirement of a celery worker running in the background to process
|
||||
celery tasks.
|
||||
|
||||
The worker can be executed using:
|
||||
|
||||
django_admin.py celery worker
|
||||
"""
|
||||
|
||||
from dev import *
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
# Requires a separate celery worker
|
||||
|
||||
CELERY_ALWAYS_EAGER = False
|
||||
|
||||
# Use django db as the broker and result store
|
||||
|
||||
BROKER_URL = 'django://'
|
||||
INSTALLED_APPS += ('djcelery.transport', )
|
||||
CELERY_RESULT_BACKEND = 'database'
|
||||
DJKOMBU_POLLING_INTERVAL = 1.0
|
||||
|
||||
# Disable transaction management because we are using a worker. Views
|
||||
# that request a task and wait for the result will deadlock otherwise.
|
||||
|
||||
MIDDLEWARE_CLASSES = tuple(
|
||||
c for c in MIDDLEWARE_CLASSES
|
||||
if c != 'django.middleware.transaction.TransactionMiddleware')
|
||||
|
||||
# Note: other alternatives for disabling transactions don't work in 1.4
|
||||
# https://code.djangoproject.com/ticket/2304
|
||||
# https://code.djangoproject.com/ticket/16039
|
||||
@@ -18,6 +18,8 @@ MITX_FEATURES['DISABLE_START_DATES'] = True
|
||||
# Until we have discussion actually working in test mode, just turn it off
|
||||
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
# Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
|
||||
WIKI_ENABLED = True
|
||||
|
||||
@@ -124,7 +126,7 @@ CACHES = {
|
||||
# Dummy secret key for dev
|
||||
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
################################## OPENID ######################################
|
||||
################################## OPENID #####################################
|
||||
MITX_FEATURES['AUTH_USE_OPENID'] = True
|
||||
MITX_FEATURES['AUTH_USE_OPENID_PROVIDER'] = True
|
||||
|
||||
@@ -136,6 +138,12 @@ OPENID_PROVIDER_TRUSTED_ROOTS = ['*']
|
||||
INSTALLED_APPS += ('external_auth',)
|
||||
INSTALLED_APPS += ('django_openid_auth',)
|
||||
|
||||
################################# CELERY ######################################
|
||||
|
||||
CELERY_ALWAYS_EAGER = True
|
||||
CELERY_RESULT_BACKEND = 'cache'
|
||||
BROKER_TRANSPORT = 'memory'
|
||||
|
||||
############################ STATIC FILES #############################
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
MEDIA_ROOT = TEST_ROOT / "uploads"
|
||||
|
||||
@@ -357,6 +357,11 @@ if settings.MITX_FEATURES.get('ENABLE_SQL_TRACKING_LOGS'):
|
||||
url(r'^event_logs/(?P<args>.+)$', 'track.views.view_tracking_log'),
|
||||
)
|
||||
|
||||
if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
|
||||
urlpatterns += (
|
||||
url(r'^status/', include('service_status.urls')),
|
||||
)
|
||||
|
||||
# FoldIt views
|
||||
urlpatterns += (
|
||||
# The path is hardcoded into their app...
|
||||
|
||||
@@ -25,6 +25,14 @@ end
|
||||
sh(django_admin(system, args.env, 'runserver', args.options))
|
||||
end
|
||||
|
||||
desc "Start #{system} Celery worker"
|
||||
task "#{system}_worker", [:options] => [:predjango] do |t, args|
|
||||
args.with_defaults(:options => default_options[system])
|
||||
django_admin = ENV['DJANGO_ADMIN_PATH'] || select_executable('django-admin.py', 'django-admin')
|
||||
command = 'celery worker'
|
||||
sh("#{django_admin} #{command} --loglevel=INFO --settings=#{system}.envs.dev_with_worker --pythonpath=. #{args.join(' ')}")
|
||||
end
|
||||
|
||||
# Per environment tasks
|
||||
environments(system).each do |env|
|
||||
desc "Attempt to import the settings file #{system}.envs.#{env} and report any errors"
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
beautifulsoup4==4.1.3
|
||||
beautifulsoup==3.2.1
|
||||
boto==2.6.0
|
||||
celery==3.0.19
|
||||
distribute==0.6.28
|
||||
django-celery==3.0.11
|
||||
django-celery==3.0.17
|
||||
django-countries==1.5
|
||||
django-followit==0.0.3
|
||||
django-keyedcache==1.4-6
|
||||
|
||||
Reference in New Issue
Block a user