File size: 2,325 Bytes
a1a6d79
c21d29c
92e41ba
a1a6d79
c21d29c
0440e99
 
a1a6d79
 
f0fe0fd
a1a6d79
f0fe0fd
 
 
a1a6d79
 
 
 
 
 
 
f0fe0fd
a1a6d79
f0fe0fd
a1a6d79
c21d29c
92e41ba
c21d29c
 
 
 
 
 
 
a08a6f4
a1a6d79
c21d29c
f0fe0fd
 
 
a1a6d79
f0fe0fd
 
a1a6d79
c21d29c
a1a6d79
f0fe0fd
92e41ba
 
 
a1a6d79
 
92e41ba
f0fe0fd
 
92e41ba
 
 
 
c21d29c
bb7c9a3
c21d29c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from asyncio import all_tasks, CancelledError, create_task, current_task, gather, get_running_loop, run
from loguru import logger
from signal import SIGINT, SIGTERM
from typing import Callable

from .containers import Container
from .core.logging import setup_logging


async def handle_shutdown_signal(*args) -> None:
    logger.info("Received shutdown signal.")
    for arg in args:
        await arg()
    logger.info("Executed shutdown tasks.")
    for task in all_tasks():
        if task is not current_task() and not task.done():
            task.cancel()
            logger.trace("Cancelled task {}.", task.get_name())
    logger.info("Cancelled all tasks.")


def create_shutdown_signal_handler(*args) -> Callable[[], None]:
    def shutdown_signal_handler() -> None:
        create_task(handle_shutdown_signal(*args))
    return shutdown_signal_handler


async def main() -> None:
    # Setup logging.
    setup_logging()
    logger.info("Starting application…")

    # Set up dependency injection container.
    container = Container()
    container.wire(packages=["ctp_slack_bot"])
    logger.debug("Created dependency injection container with providers: {}", '; '.join(container.providers))

    # Initialize/instantiate services which should be available from the start.
    await container.content_ingestion_service()
    await container.question_dispatch_service()
    http_server = await container.http_server()
    slack_service = await container.slack_service()
    task_service = await container.task_service()
    logger.debug("Initialized services.")

    # Install the shutdown signal handler.
    shutdown_signal_handler = create_shutdown_signal_handler(http_server.stop, slack_service.stop, task_service.stop)
    loop = get_running_loop()
    loop.add_signal_handler(SIGINT, shutdown_signal_handler)
    loop.add_signal_handler(SIGTERM, shutdown_signal_handler)

    # Start the HTTP server and Slack socket mode handler in the background; clean up resources when shut down.
    try:
        logger.info("Starting services…")
        await gather(http_server.start(), slack_service.start(), task_service.start())
    except CancelledError:
        logger.info("Shutting down application…")
    finally:
        await container.shutdown_resources()


if __name__ == "__main__":
    run(main())