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

Celery Mongo Results Backend get call hangs with non default db #2315

Closed
sukrit007 opened this issue Oct 11, 2014 · 3 comments
Closed

Celery Mongo Results Backend get call hangs with non default db #2315

sukrit007 opened this issue Oct 11, 2014 · 3 comments

Comments

@sukrit007
Copy link
Contributor

Given:
Celery version: 3.1.16

And:
Celery task that returns asyncresult. E.g:

@app.task
def _add(a, b):
    return a + b

@app.task
def sumall(a, b, c, d):
    return (_add.s(a,b) | _add.s(c) | _add.s(d))()

And: Celery configured to use mongodb as backend database but with different database other than celery (Issue does not happen if celery is selected as database)

CELERY_RESULT_BACKEND =  'mongodb://localhost:27017'
CELERY_MONGODB_BACKEND_SETTINGS = {
    'database': 'celery2'
}

When: I run the add task in one process and get the status by id in another process (Note: in same process issue does not happen. )

result = sumall.delay(1,2,3,4)
print(result.id)

Take the id from above process and print the status in another process using same celery settings as worker and process1 (that initiated sumall task)

result = app.AsyncResult('636c865f-df44-4e82-9f3f-d88cf13cbc13').get()  # Works (uses correct db)
result.get()  # Hangs . Uses celery db instead of 'celery2' database.

Then:
second process hangs forever when trying to get second result in the chain.

Workaround-1:

result = app.AsyncResult('636c865f-df44-4e82-9f3f-d88cf13cbc13').get()  # Works (uses correct db)
app.AsyncResult(result.id).get() # This time it uses correct db.

Workaround-2:
Do not change default database.

@sukrit007
Copy link
Contributor Author

After debugging through celery source, here is what I found :

I did figure out how celery is initializing the backend using default_app. https://github.com/celery/celery/blob/master/celery/_state.py#L83 However, _tls.current_app is always None in my case. Even though set_as_current is True for my celery app object. As a result it fall backs to default app (there by changing the database)

One possible workaround is to use :

app.set_default()

But not sure, why would _tls.current_app be None.

@ask
Copy link
Contributor

ask commented Oct 23, 2014

current_app is a thread local, so it must be set for each new thread!

Unpickling a result requires a working current_app, because the app is removed from objects when serializing.

@ask ask closed this as completed Oct 23, 2014
@sukrit007
Copy link
Contributor Author

Setting current_app did help to solve the database issue. However there seems to be a bug with host initialization during de-serialization process in MongoBackend. Even after using current_app, celery was trying to use 'localhost' as host. Here is a patch to fix this issue:

#2347

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

No branches or pull requests

2 participants