mirror of
https://github.com/langgenius/dify.git
synced 2026-11-12 06:11:12 +08:00
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
253 lines
12 KiB
Python
253 lines
12 KiB
Python
"""Compose trigger subscription, webhook, schedule and execution use cases."""
|
|
|
|
from collections.abc import Callable
|
|
from dataclasses import dataclass
|
|
from datetime import UTC, datetime
|
|
from functools import partial
|
|
|
|
from sqlalchemy.orm import Session, sessionmaker
|
|
|
|
from configs import dify_config
|
|
from core.app.file_access import DatabaseFileAccessController
|
|
from core.plugin.impl.oauth import OAuthHandler
|
|
from core.tools.tool_file_manager import ToolFileManager
|
|
from core.trigger.trigger_manager import TriggerManager
|
|
from core.trigger.utils.encryption import delete_cache_for_subscription
|
|
from enums import QuotaType
|
|
from extensions.ext_redis import RedisClientWrapper
|
|
from extensions.ext_storage import storage
|
|
from repositories.credentials.query_repository import CredentialQueryRepository
|
|
from repositories.sqlalchemy_workflow_trigger_log_repository import (
|
|
SQLAlchemyWorkflowTriggerExecutionRepository,
|
|
)
|
|
from repositories.trigger.app_repository import SQLAlchemyAppTriggerRepository
|
|
from repositories.trigger.debug_repository import RedisTriggerDebugRepository
|
|
from repositories.trigger.oauth_client_repository import TriggerOAuthClientRepository
|
|
from repositories.trigger.schedule_repository import TriggerScheduleRepository
|
|
from repositories.trigger.subscription_builder_repository import RedisTriggerSubscriptionBuilderRepository
|
|
from repositories.trigger.subscription_repository import (
|
|
RedisTriggerSubscriptionLocks,
|
|
RedisTriggerSubscriptionRefreshReservations,
|
|
TriggerSubscriptionRepository,
|
|
)
|
|
from services.async_workflow_service import AsyncWorkflowService, TriggerWorkflowQuery
|
|
from services.quota_service import QuotaService
|
|
from services.trigger.debug_service import TriggerDebugService
|
|
from services.trigger.debug_store import TriggerDebugEventStore
|
|
from services.trigger.endpoint_gateway import PluginTriggerEndpointGateway, enqueue_triggered_workflows
|
|
from services.trigger.endpoint_service import TriggerEndpointService
|
|
from services.trigger.event_gateway import PluginTriggerEventGateway
|
|
from services.trigger.event_service import TriggerEventService
|
|
from services.trigger.execution_gateway import WorkflowTriggerExecutionGateway
|
|
from services.trigger.execution_service import TriggerExecutionService
|
|
from services.trigger.execution_store import TriggerExecutionStore
|
|
from services.trigger.oauth_client_service import TriggerOAuthClientService
|
|
from services.trigger.oauth_gateway import (
|
|
OAuthProxyContextGateway,
|
|
PluginTriggerOAuthGateway,
|
|
TriggerOAuthBuilderGateway,
|
|
)
|
|
from services.trigger.oauth_service import TriggerOAuthService
|
|
from services.trigger.provider_gateway import PluginTriggerProviderQuery
|
|
from services.trigger.provider_query import TriggerProviderQuery
|
|
from services.trigger.schedule_gateway import ScheduleWorkflowGateway, publish_schedules
|
|
from services.trigger.schedule_service import SchedulePublicationService, TriggerScheduleService
|
|
from services.trigger.subscription_binding_service import (
|
|
TriggerSubscriptionBindingQuery,
|
|
TriggerSubscriptionBindingService,
|
|
)
|
|
from services.trigger.subscription_codec import ProviderTriggerSubscriptionCodec
|
|
from services.trigger.subscription_gateway import (
|
|
PluginTriggerSubscriptionGateway,
|
|
enqueue_subscription_refresh,
|
|
invalidate_subscription_properties,
|
|
)
|
|
from services.trigger.subscription_query_service import TriggerSubscriptionQueryService
|
|
from services.trigger.subscription_refresh_service import TriggerSubscriptionRefreshService
|
|
from services.trigger.subscription_renewal_service import TriggerSubscriptionRenewalService
|
|
from services.trigger.subscription_service import TriggerSubscriptionService
|
|
from services.trigger.trigger_request_service import TriggerHttpRequestCachingService
|
|
from services.trigger.trigger_subscription_builder_service import TriggerSubscriptionBuilderService
|
|
from services.trigger.webhook_gateway import ToolWebhookFiles
|
|
from services.trigger.webhook_service import (
|
|
WebhookBindingService,
|
|
WebhookFiles,
|
|
WebhookService,
|
|
)
|
|
from services.trigger.workflow_dispatch_service import PluginTriggerWorkflowDispatchService, TriggerEndUserProvisioner
|
|
from services.workflow.queue_dispatcher import CeleryWorkflowQueuePublisher
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class TriggerServices:
|
|
providers: TriggerProviderQuery
|
|
subscriptions: TriggerSubscriptionQueryService
|
|
binding_queries: TriggerSubscriptionBindingQuery
|
|
create_binding_service: Callable[[Session], TriggerSubscriptionBindingService]
|
|
subscription_management: TriggerSubscriptionService
|
|
subscription_renewal: TriggerSubscriptionRenewalService
|
|
subscription_refresh: TriggerSubscriptionRefreshService
|
|
builders: TriggerSubscriptionBuilderService
|
|
endpoints: TriggerEndpointService
|
|
events: TriggerEventService
|
|
debug: TriggerDebugService
|
|
debug_events: TriggerDebugEventStore
|
|
workflow_dispatch: AsyncWorkflowService
|
|
executions: TriggerExecutionService
|
|
execution_logs: TriggerExecutionStore
|
|
webhooks: WebhookService
|
|
webhook_files: WebhookFiles
|
|
webhook_draft_bindings: WebhookBindingService
|
|
create_webhook_publication_service: Callable[[Session], WebhookBindingService]
|
|
plugin_workflow_dispatch: PluginTriggerWorkflowDispatchService
|
|
schedules: TriggerScheduleService
|
|
create_schedule_publication_service: Callable[[Session], SchedulePublicationService]
|
|
oauth_clients: TriggerOAuthClientService
|
|
oauth: TriggerOAuthService
|
|
|
|
|
|
def build_trigger_services(
|
|
*,
|
|
database_client: sessionmaker[Session],
|
|
redis: RedisClientWrapper,
|
|
credentials: CredentialQueryRepository,
|
|
subscriptions: TriggerSubscriptionRepository,
|
|
workflow_queries: TriggerWorkflowQuery,
|
|
trigger_end_users: TriggerEndUserProvisioner,
|
|
mark_rate_limited: Callable[[str], None],
|
|
) -> TriggerServices:
|
|
trigger_providers = PluginTriggerProviderQuery()
|
|
subscription_provider = PluginTriggerSubscriptionGateway()
|
|
subscription_locks = RedisTriggerSubscriptionLocks(redis=redis)
|
|
subscription_codec = ProviderTriggerSubscriptionCodec()
|
|
trigger_subscription_management = TriggerSubscriptionService(
|
|
subscriptions=subscriptions,
|
|
providers=subscription_provider,
|
|
locks=subscription_locks,
|
|
codec=subscription_codec,
|
|
invalidate_cache=delete_cache_for_subscription,
|
|
)
|
|
trigger_builders = TriggerSubscriptionBuilderService(
|
|
builders=RedisTriggerSubscriptionBuilderRepository(redis=redis),
|
|
get_provider=TriggerManager.get_trigger_provider,
|
|
subscribe=TriggerManager.subscribe_trigger,
|
|
create_subscription=trigger_subscription_management.create,
|
|
)
|
|
trigger_oauth_provider = PluginTriggerOAuthGateway(oauth=OAuthHandler())
|
|
trigger_oauth_clients = TriggerOAuthClientService(
|
|
clients=TriggerOAuthClientRepository(session_factory=database_client),
|
|
providers=trigger_oauth_provider,
|
|
)
|
|
trigger_subscriptions = TriggerSubscriptionQueryService(
|
|
credentials=credentials, schemas=trigger_providers, subscriptions=subscriptions
|
|
)
|
|
renewal = TriggerSubscriptionRenewalService(
|
|
subscriptions=subscriptions,
|
|
providers=subscription_provider,
|
|
oauth=trigger_oauth_provider,
|
|
clients=trigger_oauth_clients,
|
|
locks=subscription_locks,
|
|
codec=subscription_codec,
|
|
credential_threshold=dify_config.TRIGGER_PROVIDER_CREDENTIAL_THRESHOLD_SECONDS,
|
|
subscription_threshold=dify_config.TRIGGER_PROVIDER_SUBSCRIPTION_THRESHOLD_SECONDS,
|
|
console_api_url=dify_config.CONSOLE_API_URL,
|
|
invalidate_cache=delete_cache_for_subscription,
|
|
invalidate_properties=invalidate_subscription_properties,
|
|
)
|
|
trigger_requests = TriggerHttpRequestCachingService(storage=storage)
|
|
trigger_debug_events = RedisTriggerDebugRepository(redis=redis)
|
|
trigger_events = TriggerEventService(
|
|
subscriptions=trigger_subscriptions,
|
|
plugins=PluginTriggerEventGateway(),
|
|
requests=trigger_requests,
|
|
)
|
|
execution_logs = SQLAlchemyWorkflowTriggerExecutionRepository(session_factory=database_client)
|
|
execution_runtime = WorkflowTriggerExecutionGateway(
|
|
models=execution_logs, logs=execution_logs, session_factory=database_client
|
|
)
|
|
queues = CeleryWorkflowQueuePublisher()
|
|
workflow_dispatch = AsyncWorkflowService(
|
|
workflows=workflow_queries, logs=execution_logs, queues=queues, reserve_quota=QuotaService.reserve
|
|
)
|
|
app_triggers = SQLAlchemyAppTriggerRepository(session_factory=database_client)
|
|
schedules = TriggerScheduleRepository(session_factory=database_client)
|
|
return TriggerServices(
|
|
providers=trigger_providers,
|
|
subscriptions=trigger_subscriptions,
|
|
binding_queries=subscriptions,
|
|
# Bind only for the duration of the caller's publication transaction.
|
|
create_binding_service=lambda session: TriggerSubscriptionBindingService(
|
|
sync_bindings=partial(subscriptions.sync_workflow_bindings, session=session)
|
|
),
|
|
events=trigger_events,
|
|
debug_events=trigger_debug_events,
|
|
debug=TriggerDebugService(
|
|
events=trigger_debug_events,
|
|
schedules=trigger_debug_events,
|
|
invoke_plugin_event=trigger_events.invoke_debug,
|
|
now=lambda: datetime.now(UTC),
|
|
),
|
|
workflow_dispatch=workflow_dispatch,
|
|
executions=TriggerExecutionService(logs=execution_logs, run=execution_runtime.run),
|
|
execution_logs=execution_logs,
|
|
webhooks=WebhookService(
|
|
webhooks=app_triggers,
|
|
end_users=trigger_end_users,
|
|
dispatch=workflow_dispatch,
|
|
reserve_quota=QuotaService.reserve,
|
|
mark_rate_limited=mark_rate_limited,
|
|
),
|
|
webhook_files=ToolWebhookFiles(manager=ToolFileManager(), access=DatabaseFileAccessController()),
|
|
webhook_draft_bindings=WebhookBindingService(sync_bindings=app_triggers.sync_draft_webhooks),
|
|
# Publish binding changes atomically with the workflow that owns them.
|
|
create_webhook_publication_service=lambda session: WebhookBindingService(
|
|
sync_bindings=partial(app_triggers.sync_webhooks, session=session, remove_stale=True)
|
|
),
|
|
plugin_workflow_dispatch=PluginTriggerWorkflowDispatchService(
|
|
workflows=workflow_queries,
|
|
logs=execution_logs,
|
|
queues=queues,
|
|
dispatch=workflow_dispatch,
|
|
events=trigger_events,
|
|
bindings=subscriptions,
|
|
end_users=trigger_end_users,
|
|
reserve_quota=QuotaService.reserve,
|
|
mark_rate_limited=mark_rate_limited,
|
|
),
|
|
schedules=TriggerScheduleService(
|
|
schedules=schedules,
|
|
publish=publish_schedules,
|
|
dispatch=ScheduleWorkflowGateway(workflows=workflow_dispatch),
|
|
reserve=partial(QuotaService.reserve, QuotaType.TRIGGER),
|
|
mark_rate_limited=mark_rate_limited,
|
|
now=lambda: datetime.now(UTC),
|
|
batch_size=dify_config.WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE,
|
|
max_dispatch_per_tick=dify_config.WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK,
|
|
),
|
|
create_schedule_publication_service=lambda session: SchedulePublicationService(
|
|
sync_schedule=partial(schedules.sync_publication, session=session), now=lambda: datetime.now(UTC)
|
|
),
|
|
subscription_management=trigger_subscription_management,
|
|
subscription_renewal=renewal,
|
|
subscription_refresh=TriggerSubscriptionRefreshService(
|
|
subscriptions=subscriptions,
|
|
reservations=RedisTriggerSubscriptionRefreshReservations(redis=redis),
|
|
publish=enqueue_subscription_refresh,
|
|
renewal=renewal,
|
|
),
|
|
builders=trigger_builders,
|
|
endpoints=TriggerEndpointService(
|
|
subscriptions=subscriptions,
|
|
provider=PluginTriggerEndpointGateway(),
|
|
requests=trigger_requests,
|
|
publish=enqueue_triggered_workflows,
|
|
),
|
|
oauth_clients=trigger_oauth_clients,
|
|
oauth=TriggerOAuthService(
|
|
clients=trigger_oauth_clients,
|
|
providers=trigger_oauth_provider,
|
|
contexts=OAuthProxyContextGateway(),
|
|
builders=TriggerOAuthBuilderGateway(builders=trigger_builders),
|
|
),
|
|
)
|