mirror of
https://github.com/langgenius/dify.git
synced 2026-03-09 17:36:44 +08:00
Signed-off-by: majiayu000 <1835304752@qq.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Signed-off-by: -LAN- <laipz8200@outlook.com> Signed-off-by: yihong0618 <zouzou0208@gmail.com> Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com> Co-authored-by: 盐粒 Yanli <yanli@dify.ai> Co-authored-by: wangxiaolei <fatelei@gmail.com> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Cursx <33718736+Cursx@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: lif <1835304752@qq.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: fenglin <790872612@qq.com> Co-authored-by: qiaofenglin <qiaofenglin@baidu.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: TomoOkuyama <49631611+TomoOkuyama@users.noreply.github.com> Co-authored-by: Tomo Okuyama <tomo.okuyama@intersystems.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: zyssyz123 <916125788@qq.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: CodingOnStar <hanxujiang@dify.ai> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: Xiangxuan Qu <fghpdf@outlook.com> Co-authored-by: fghpdf <fghpdf@users.noreply.github.com> Co-authored-by: coopercoder <whitetiger0127@163.com> Co-authored-by: zhaiguangpeng <zhaiguangpeng@didiglobal.com> Co-authored-by: Junyan Qin (Chin) <rockchinq@gmail.com> Co-authored-by: E.G <146701565+GlobalStar117@users.noreply.github.com> Co-authored-by: GlobalStar117 <GlobalStar117@users.noreply.github.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: heyszt <270985384@qq.com> Co-authored-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Co-authored-by: Yeuoly <45712896+Yeuoly@users.noreply.github.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: moonpanda <chuanzegao@163.com> Co-authored-by: warlocgao <warlocgao@tencent.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: KVOJJJin <jzongcode@gmail.com> Co-authored-by: eux <euxx@users.noreply.github.com> Co-authored-by: bangjiehan <bangjiehan@gmail.com> Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: Nie Ronghua <nieronghua@sf-express.com> Co-authored-by: JQSevenMiao <141806521+JQSevenMiao@users.noreply.github.com> Co-authored-by: jiasiqi <jiasiqi3@tal.com> Co-authored-by: Seokrin Taron Sung <sungsjade@gmail.com> Co-authored-by: CrabSAMA <40541269+CrabSAMA@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: yihong <zouzou0208@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: yessenia <yessenia.contact@gmail.com> Co-authored-by: Jax <anobaka@qq.com> Co-authored-by: niveshdandyan <155956228+niveshdandyan@users.noreply.github.com> Co-authored-by: OSS Contributor <oss-contributor@example.com> Co-authored-by: niveshdandyan <niveshdandyan@users.noreply.github.com> Co-authored-by: Sean Kenneth Doherty <Smaster7772@gmail.com>
190 lines
7.8 KiB
Python
190 lines
7.8 KiB
Python
import ssl
|
|
from datetime import timedelta
|
|
from typing import Any
|
|
|
|
import pytz
|
|
from celery import Celery, Task
|
|
from celery.schedules import crontab
|
|
|
|
from configs import dify_config
|
|
from dify_app import DifyApp
|
|
|
|
|
|
def _get_celery_ssl_options() -> dict[str, Any] | None:
|
|
"""Get SSL configuration for Celery broker/backend connections."""
|
|
# Only apply SSL if we're using Redis as broker/backend
|
|
if not dify_config.BROKER_USE_SSL:
|
|
return None
|
|
|
|
# Check if Celery is actually using Redis
|
|
broker_is_redis = dify_config.CELERY_BROKER_URL and (
|
|
dify_config.CELERY_BROKER_URL.startswith("redis://") or dify_config.CELERY_BROKER_URL.startswith("rediss://")
|
|
)
|
|
|
|
if not broker_is_redis:
|
|
return None
|
|
|
|
# Map certificate requirement strings to SSL constants
|
|
cert_reqs_map = {
|
|
"CERT_NONE": ssl.CERT_NONE,
|
|
"CERT_OPTIONAL": ssl.CERT_OPTIONAL,
|
|
"CERT_REQUIRED": ssl.CERT_REQUIRED,
|
|
}
|
|
|
|
ssl_cert_reqs = cert_reqs_map.get(dify_config.REDIS_SSL_CERT_REQS, ssl.CERT_NONE)
|
|
|
|
ssl_options = {
|
|
"ssl_cert_reqs": ssl_cert_reqs,
|
|
"ssl_ca_certs": dify_config.REDIS_SSL_CA_CERTS,
|
|
"ssl_certfile": dify_config.REDIS_SSL_CERTFILE,
|
|
"ssl_keyfile": dify_config.REDIS_SSL_KEYFILE,
|
|
}
|
|
|
|
return ssl_options
|
|
|
|
|
|
def init_app(app: DifyApp) -> Celery:
|
|
class FlaskTask(Task):
|
|
def __call__(self, *args: object, **kwargs: object) -> object:
|
|
from core.logging.context import init_request_context
|
|
|
|
with app.app_context():
|
|
# Initialize logging context for this task (similar to before_request in Flask)
|
|
init_request_context()
|
|
return self.run(*args, **kwargs)
|
|
|
|
broker_transport_options = {}
|
|
|
|
if dify_config.CELERY_USE_SENTINEL:
|
|
broker_transport_options = {
|
|
"master_name": dify_config.CELERY_SENTINEL_MASTER_NAME,
|
|
"sentinel_kwargs": {
|
|
"socket_timeout": dify_config.CELERY_SENTINEL_SOCKET_TIMEOUT,
|
|
"password": dify_config.CELERY_SENTINEL_PASSWORD,
|
|
},
|
|
}
|
|
|
|
celery_app = Celery(
|
|
app.name,
|
|
task_cls=FlaskTask,
|
|
broker=dify_config.CELERY_BROKER_URL,
|
|
backend=dify_config.CELERY_BACKEND,
|
|
)
|
|
|
|
celery_app.conf.update(
|
|
result_backend=dify_config.CELERY_RESULT_BACKEND,
|
|
broker_transport_options=broker_transport_options,
|
|
broker_connection_retry_on_startup=True,
|
|
worker_log_format=dify_config.LOG_FORMAT,
|
|
worker_task_log_format=dify_config.LOG_FORMAT,
|
|
worker_hijack_root_logger=False,
|
|
timezone=pytz.timezone(dify_config.LOG_TZ or "UTC"),
|
|
task_ignore_result=True,
|
|
)
|
|
|
|
# Apply SSL configuration if enabled
|
|
ssl_options = _get_celery_ssl_options()
|
|
if ssl_options:
|
|
celery_app.conf.update(
|
|
broker_use_ssl=ssl_options,
|
|
# Also apply SSL to the backend if it's Redis
|
|
redis_backend_use_ssl=ssl_options if dify_config.CELERY_BACKEND == "redis" else None,
|
|
)
|
|
|
|
if dify_config.LOG_FILE:
|
|
celery_app.conf.update(
|
|
worker_logfile=dify_config.LOG_FILE,
|
|
)
|
|
|
|
celery_app.set_default()
|
|
app.extensions["celery"] = celery_app
|
|
|
|
imports = [
|
|
"tasks.async_workflow_tasks", # trigger workers
|
|
"tasks.trigger_processing_tasks", # async trigger processing
|
|
"tasks.generate_summary_index_task", # summary index generation
|
|
"tasks.regenerate_summary_index_task", # summary index regeneration
|
|
]
|
|
day = dify_config.CELERY_BEAT_SCHEDULER_TIME
|
|
|
|
# if you add a new task, please add the switch to CeleryScheduleTasksConfig
|
|
beat_schedule = {}
|
|
if dify_config.ENABLE_CLEAN_EMBEDDING_CACHE_TASK:
|
|
imports.append("schedule.clean_embedding_cache_task")
|
|
beat_schedule["clean_embedding_cache_task"] = {
|
|
"task": "schedule.clean_embedding_cache_task.clean_embedding_cache_task",
|
|
"schedule": crontab(minute="0", hour="2", day_of_month=f"*/{day}"),
|
|
}
|
|
if dify_config.ENABLE_CLEAN_UNUSED_DATASETS_TASK:
|
|
imports.append("schedule.clean_unused_datasets_task")
|
|
beat_schedule["clean_unused_datasets_task"] = {
|
|
"task": "schedule.clean_unused_datasets_task.clean_unused_datasets_task",
|
|
"schedule": crontab(minute="0", hour="3", day_of_month=f"*/{day}"),
|
|
}
|
|
if dify_config.ENABLE_CREATE_TIDB_SERVERLESS_TASK:
|
|
imports.append("schedule.create_tidb_serverless_task")
|
|
beat_schedule["create_tidb_serverless_task"] = {
|
|
"task": "schedule.create_tidb_serverless_task.create_tidb_serverless_task",
|
|
"schedule": crontab(minute="0", hour="*"),
|
|
}
|
|
if dify_config.ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK:
|
|
imports.append("schedule.update_tidb_serverless_status_task")
|
|
beat_schedule["update_tidb_serverless_status_task"] = {
|
|
"task": "schedule.update_tidb_serverless_status_task.update_tidb_serverless_status_task",
|
|
"schedule": timedelta(minutes=10),
|
|
}
|
|
if dify_config.ENABLE_CLEAN_MESSAGES:
|
|
imports.append("schedule.clean_messages")
|
|
beat_schedule["clean_messages"] = {
|
|
"task": "schedule.clean_messages.clean_messages",
|
|
"schedule": crontab(minute="0", hour="4", day_of_month=f"*/{day}"),
|
|
}
|
|
if dify_config.ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK:
|
|
imports.append("schedule.mail_clean_document_notify_task")
|
|
beat_schedule["mail_clean_document_notify_task"] = {
|
|
"task": "schedule.mail_clean_document_notify_task.mail_clean_document_notify_task",
|
|
"schedule": crontab(minute="0", hour="10", day_of_week="1"),
|
|
}
|
|
if dify_config.ENABLE_DATASETS_QUEUE_MONITOR:
|
|
imports.append("schedule.queue_monitor_task")
|
|
beat_schedule["datasets-queue-monitor"] = {
|
|
"task": "schedule.queue_monitor_task.queue_monitor_task",
|
|
"schedule": timedelta(minutes=dify_config.QUEUE_MONITOR_INTERVAL or 30),
|
|
}
|
|
if dify_config.ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK and dify_config.MARKETPLACE_ENABLED:
|
|
imports.append("schedule.check_upgradable_plugin_task")
|
|
imports.append("tasks.process_tenant_plugin_autoupgrade_check_task")
|
|
beat_schedule["check_upgradable_plugin_task"] = {
|
|
"task": "schedule.check_upgradable_plugin_task.check_upgradable_plugin_task",
|
|
"schedule": crontab(minute="*/15"),
|
|
}
|
|
if dify_config.WORKFLOW_LOG_CLEANUP_ENABLED:
|
|
# 2:00 AM every day
|
|
imports.append("schedule.clean_workflow_runlogs_precise")
|
|
beat_schedule["clean_workflow_runlogs_precise"] = {
|
|
"task": "schedule.clean_workflow_runlogs_precise.clean_workflow_runlogs_precise",
|
|
"schedule": crontab(minute="0", hour="2"),
|
|
}
|
|
if dify_config.ENABLE_WORKFLOW_RUN_CLEANUP_TASK:
|
|
# for saas only
|
|
imports.append("schedule.clean_workflow_runs_task")
|
|
beat_schedule["clean_workflow_runs_task"] = {
|
|
"task": "schedule.clean_workflow_runs_task.clean_workflow_runs_task",
|
|
"schedule": crontab(minute="0", hour="0"),
|
|
}
|
|
if dify_config.ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK:
|
|
imports.append("schedule.workflow_schedule_task")
|
|
beat_schedule["workflow_schedule_task"] = {
|
|
"task": "schedule.workflow_schedule_task.poll_workflow_schedules",
|
|
"schedule": timedelta(minutes=dify_config.WORKFLOW_SCHEDULE_POLLER_INTERVAL),
|
|
}
|
|
if dify_config.ENABLE_TRIGGER_PROVIDER_REFRESH_TASK:
|
|
imports.append("schedule.trigger_provider_refresh_task")
|
|
beat_schedule["trigger_provider_refresh"] = {
|
|
"task": "schedule.trigger_provider_refresh_task.trigger_provider_refresh",
|
|
"schedule": timedelta(minutes=dify_config.TRIGGER_PROVIDER_REFRESH_INTERVAL),
|
|
}
|
|
celery_app.conf.update(beat_schedule=beat_schedule, imports=imports)
|
|
|
|
return celery_app
|