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

Allow a custom Executor in App #453

Merged
merged 6 commits into from
Aug 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion slack_bolt/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
import time
from concurrent.futures import Executor
from concurrent.futures.thread import ThreadPoolExecutor
from http.server import SimpleHTTPRequestHandler, HTTPServer
from typing import List, Union, Pattern, Callable, Dict, Optional, Sequence, Any
Expand Down Expand Up @@ -113,6 +114,8 @@ def __init__(
oauth_flow: Optional[OAuthFlow] = None,
# No need to set (the value is used only in response to ssl_check requests)
verification_token: Optional[str] = None,
# Set this one only when you want to customize the executor
listener_executor: Optional[Executor] = None,
chrisbouchard marked this conversation as resolved.
Show resolved Hide resolved
):
"""Bolt App that provides functionalities to register middleware/listeners.

Expand Down Expand Up @@ -173,6 +176,8 @@ def message_hello(message, say):
oauth_settings: The settings related to Slack app installation flow (OAuth flow)
oauth_flow: Instantiated `slack_bolt.oauth.OAuthFlow`. This is always prioritized over oauth_settings.
verification_token: Deprecated verification mechanism. This can used only for ssl_check requests.
listener_executor: Custom executor to run background tasks. If absent, the default `ThreadPoolExecutor` will
be used.
"""
signing_secret = signing_secret or os.environ.get("SLACK_SIGNING_SECRET")
token = token or os.environ.get("SLACK_BOT_TOKEN")
Expand Down Expand Up @@ -302,7 +307,9 @@ def message_hello(message, say):
self._middleware_list: List[Union[Callable, Middleware]] = []
self._listeners: List[Listener] = []

listener_executor = ThreadPoolExecutor(max_workers=5)
if listener_executor is None:
listener_executor = ThreadPoolExecutor(max_workers=5)

self._process_before_response = process_before_response
self._listener_runner = ThreadListenerRunner(
logger=self._framework_logger,
Expand Down
4 changes: 2 additions & 2 deletions slack_bolt/lazy_listener/thread_runner.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures import Executor
from logging import Logger
from typing import Callable

Expand All @@ -13,7 +13,7 @@ class ThreadLazyListenerRunner(LazyListenerRunner):
def __init__(
self,
logger: Logger,
executor: ThreadPoolExecutor,
executor: Executor,
):
self.logger = logger
self.executor = executor
Expand Down
6 changes: 3 additions & 3 deletions slack_bolt/listener/thread_runner.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import time
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures import Executor
from logging import Logger
from typing import Optional, Callable

Expand All @@ -22,7 +22,7 @@ class ThreadListenerRunner:
process_before_response: bool
listener_error_handler: ListenerErrorHandler
listener_completion_handler: ListenerCompletionHandler
listener_executor: ThreadPoolExecutor
listener_executor: Executor
lazy_listener_runner: LazyListenerRunner

def __init__(
Expand All @@ -31,7 +31,7 @@ def __init__(
process_before_response: bool,
listener_error_handler: ListenerErrorHandler,
listener_completion_handler: ListenerCompletionHandler,
listener_executor: ThreadPoolExecutor,
listener_executor: Executor,
lazy_listener_runner: LazyListenerRunner,
):
self.logger = logger
Expand Down
18 changes: 18 additions & 0 deletions tests/scenario_tests/test_app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from concurrent.futures import Executor

import pytest
from slack_sdk import WebClient
from slack_sdk.oauth.installation_store import FileInstallationStore
Expand Down Expand Up @@ -56,6 +58,22 @@ def test_listener_registration_error(self):
with pytest.raises(BoltError):
app.action({"type": "invalid_type", "action_id": "a"})(self.simple_listener)

def test_listener_executor(self):
class TestExecutor(Executor):
"""A executor that does nothing for testing"""

pass

executor = TestExecutor()
app = App(
signing_secret="valid",
client=self.web_client,
listener_executor=executor,
)

assert app.listener_runner.listener_executor == executor
assert app.listener_runner.lazy_listener_runner.executor == executor

# --------------------------
# single team auth
# --------------------------
Expand Down