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

Replace Celery with RQ (except for execute_query tasks) #4093

Merged
merged 74 commits into from
Oct 15, 2019
Merged

Replace Celery with RQ (except for execute_query tasks) #4093

merged 74 commits into from
Oct 15, 2019

Conversation

rauchy
Copy link
Contributor

@rauchy rauchy commented Aug 21, 2019

What type of PR is this? (check all applicable)

  • Refactor

Description

As a first probe towards migrating to RQ, I'm interested in trying to swap out Celery beat and all non-execute-query tasks and replace them with RQ.

Related Tickets & Documents

Towards #4092

build: .
command: dev_rq_worker
deploy:
replicas: 2
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Left this here for discussion - if one would want to allow multiple workers running simultaneously using docker-compose, one would have to run docker-compose --compatibility up

Copy link
Member

Choose a reason for hiding this comment

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

Isn't deploy only for Docker Swarm deployments? Have you considered using scale option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I understand correctly, the scale option is deprecated. One could use the --scale CLI option, and that would have the same consequence as using --compatibility. I just saw the deploy.replicas option as a better source of documentation for anyone who would want to scale through docker-compose.

Copy link
Member

Choose a reason for hiding this comment

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

You're right. They deprecated it in v3 😒 I fail to see the logic behind this move, specially when they recommend not using --compatibility in production.

Considering we have no intention of using Swarm -- maybe we should switch to v2?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have at least one thing we need from v3.2 - bind volumes (for proper code reloading), so v2 is not an option. I guess it'll be best to recommend the --scale option outside this file. Where do you think would be the best place to do so?

Copy link
Member

Choose a reason for hiding this comment

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

Do you remember what's the difference between how we define the volume for server and worker? I know you added it when working on auto restart, but from looking at the docs I fail to understand the difference.

If it is required, we can consider downgrading the production compose file to v2 as there the scale configuration is more important.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

server is using the default volume volume type, because Flask's auto reloading works fine with it. For worker (or anything that we use watchmedo for) we need a bind volume type for FSEvents to play nicely with macOS.

We could definitely use v2 for production compose files though.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, as this is all interim -- let's move on and revisit before migrating everything to RQ.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, for now I've removed the deploy.replicas key.

def worker(queues='default'):
with Connection(redis_connection):
w = Worker(queues)
w.work()
Copy link
Member

Choose a reason for hiding this comment

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

I should note that there is flask-rq2 which provides a Flask friendly API for this.

Copy link
Member

Choose a reason for hiding this comment

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

(I'm its author)

redash/__init__.py Outdated Show resolved Hide resolved
requirements.txt Show resolved Hide resolved
redash/cli/rq.py Outdated Show resolved Hide resolved
redash/cli/rq.py Outdated Show resolved Hide resolved
Omer Lachish added 2 commits September 22, 2019 13:24
…le using docker-compose would be the --scale CLI option, which will be described in the knowledge based
@arikfr
Copy link
Member

arikfr commented Oct 10, 2019

@NicolasLM We're planning on merging this soon into master. Anything we can do to make your life easier post the merge?

@NicolasLM
Copy link
Contributor

@NicolasLM We're planning on merging this soon into master. Anything we can do to make your life easier post the merge?

Thank you for the heads up. I don't expect much trouble with running this code on Python 3, the bulk of the work will probably be resolving conflicts.

@rauchy
Copy link
Contributor Author

rauchy commented Oct 15, 2019

If we can't just directly use the function, why not return that definitions dict in this function and call schedule in redash.schedule?

@arikfr yeah that makes sense. I've used the opportunity to schedule standard jobs in the same way to make both invocations appear the same in 4fb49c0.

@arikfr
Copy link
Member

arikfr commented Oct 15, 2019

When we merge this we should post an update on Development mentioning that master is in a hybrid state at the moment and not recommended for general consumption.

@rauchy rauchy merged commit 5a5fdec into master Oct 15, 2019
cleanup_query_results,
version_check, send_aggregated_errors)

rq_scheduler = Scheduler(connection=redis_connection,
Copy link
Member

Choose a reason for hiding this comment

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

In Python 3 we use decode_responses=True, while rq-scheduler expects it to be False and uses decode on values it receives:

https://github.com/rq/rq-scheduler/blob/061488e79b82af215f7f98fa1554a0aa84dfd62f/rq_scheduler/scheduler.py#L321

When porting this to Python 3, we should probably create a Redis connection for it without the decode_responses change 🤔 We can create a "factory" function for creating the Redis connection and move the logic of mangling the Redis URL there (and make it optional).

Another option to consider is to revert to not decoding responses and do it where needed. It just felt redundant, so I was hoping to avoid it.

@rauchy @NicolasLM

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.

4 participants