Skip to content

can't shutdown slackclient correctly when other async tasks/futures are running #522

@lundjordan

Description

@lundjordan

Description

I have a slack client that has both a RTMClient always running but periodically I also check state of something and will create a WebClient to send a message if a state condition is met. I do this via asyncio (passing async_run) to the client inits.

When I add other async futures/tasks, I can no longer shutdown the RTMClient cleanly with a SIGINT/ctrl-c. The debug logs claim the client is shutting down but it will just repeat that every time I hit ctrl-c and keep running.

I see in the source that the RTMClient will catch and handle terminate signals. Unless I'm missing something about how asyncio works, perhaps the client is not shutting down and closing properly?

What type of issue is this? (place an x in one of the [ ])

  • bug
  • enhancement (feature request)
  • question
  • documentation related
  • testing related
  • discussion

Requirements (place an x in each of the [ ])

  • I've read and understood the Contributing guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've searched for any related issues and avoided creating a duplicate issue.

Bug Report

Filling out the following details about bugs will help us solve your issue sooner.

Reproducible in:

slackclient version: 2.2.0

python version: 3.7.4

OS version(s): macOS 10.14.6

Steps to reproduce:

I created a basic example script to simulate this behaviour. It creates a RTMClient and a simple sleep based tasks:

example.py

import asyncio
import logging
import os

import slack

logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)


async def sleepy_count(name, sleep_for):
    for i in range(10):
        await asyncio.sleep(sleep_for)
        LOGGER.debug(f"{name} - slept {i + 1} times.")


async def slack_client_and_sleeps():
    # real-time-messaging Slack client
    client = slack.RTMClient(token=os.environ['SLACK_API_TOKEN'], run_async=True)

    sleepy_count_task = asyncio.create_task(sleepy_count("first counter", 1))
    sleepy_count_task2 = asyncio.create_task(sleepy_count("second counter", 3))

    await asyncio.gather(client.start(), sleepy_count_task, sleepy_count_task2)


async def slack_client():
    # real-time-messaging Slack client
    client = slack.RTMClient(token=os.environ['SLACK_API_TOKEN'], run_async=True)

    await asyncio.gather(client.start())


async def sleeps():
    sleepy_count_task = asyncio.create_task(sleepy_count("first counter", 1))
    sleepy_count_task2 = asyncio.create_task(sleepy_count("second counter", 3))

    await asyncio.gather(sleepy_count_task, sleepy_count_task2)


if __name__ == "__main__":
    #  sigint closes program correctly
    #  asyncio.run(slack_client())

    # sigint closes program correctly
    #  asyncio.run(sleeps())

    # sigint doesn't actually close properly
    #  asyncio.run(slack_client_and_sleeps())

Expected result:

If I un-comment asyncio.run(slack_client_and_sleeps()) and run the script, I would have thought the program would close just like it does with asyncio.run(sleeps()) and asyncio.run(slack_client()) but it doesn't.

Actual result:

running the script with asyncio.run(slack_client_and_sleeps()) and sending SIGINT a few times doesn't actually stop the program:

shell

DEBUG:asyncio:Using selector: KqueueSelector
DEBUG:slack.rtm.client:Retrieving websocket info.
DEBUG:slack.web.slack_response:Received the following response: {'ok': True, # SCRUBBING CHANNEL AND WORKSPACE DETAILS ...}
DEBUG:__main__:first counter - slept 1 times.
DEBUG:slack.rtm.client:The Websocket connection has been opened.
DEBUG:__main__:first counter - slept 2 times.
^CDEBUG:slack.rtm.client:The Slack RTMClient is shutting down.
WARNING:slack.rtm.client:Websocket was closed.
DEBUG:__main__:second counter - slept 1 times.
DEBUG:__main__:first counter - slept 3 times.
^CDEBUG:slack.rtm.client:The Slack RTMClient is shutting down.

I'm then forced to kill -9ing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Version: 2xarea:concurrencyIssues and PRs related to concurrencybugM-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documentedrtm-client

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions