[ECS] [Feature Request]: Implement a delay between CloudMap DeregisterInstance and when task is stopped during service update.
- Dominant language
- Shell
- Stars
- 5.4k
- Forks
- 334
- PR merge metrics
- No merged PRs in 30d
Description
### Community Note
* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment
**Tell us about your request**
When using API gateway and Cloud Map integration, there is an issue with requests being sent to tasks after SIGTERM is received when tasks are stopped during service updates. A delay between the time the CloudMap instance is deregistered and when the task is stopped it would allow for CloudMap to stop routing traffic to the task.
**Which service(s) is this request for?**
This could be Fargate, and ECS
**Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?**
API gateway uses CloudMap's DiscoverInstances API to determine the targets. During a service update, the task is stopped as soon as the target is deregistered. However, there is a cache on the API gateway side as requests are still routed to tasks which have received SIGTERM, resulting in 503 errors. A delay between the deregistration and StopTask would reduce these errors during the service update.
**Are you currently working around this issue?**
It is possible to use ALB, but would prefer to use service discovery and Cloud Map.
**Additional context**
To replicate the setup, API gateway with ECS Service Discovery integration is detailed in the below AWS blog post:
https://aws.amazon.com/blogs/architecture/field-notes-integrating-http-apis-with-aws-cloud-map-and-amazon-ecs-services/
The example uses a Flask App, accessed using the below S3 link:
https://cloudmap-shared.s3.eu-central-1.amazonaws.com/ExampleFlask.zip
We can modify `app.py` so that it can keep accepting requests after receiving SIGTERM. Below code snippet keeps accepting requests for 60 seconds after receiving SIGTERM:
```
from flask import Flask
import json
import signal
import time
import logging
import threading
import os
app = Flask(__name__)
app.logger.setLevel(logging.INFO)
@app.route('/')
def home():
return json.dumps({'result': 'Basic HTTP API Test'})
# sleep is a blocking action, hence creating another thread to sleep to prevent blocking of flask thread
def sleep_execution():
time.sleep(60)
app.logger.info('Done')
os._exit(1)
def shutdown(signum, frame):
app.logger.info('Caught SIGTERM, sleeping for 60 seconds')
sleep_thread = threading.Thread(target=sleep_execution)
sleep_thread.start()
if __name__== "__main__":
signal.signal(signal.SIGTERM, shutdown)
app_thread = threading.Thread(target=app.run(host='0.0.0.0',port=80))
app_thread.start()
```
`stopTimeout` in the ECS task definition should also be updated to 90 seconds. In my test, I am only using 1 task.
After initial deploy, we can force deploy a new deployment to replace the existing tasks. We can continuously access the API gateway endpoint during the update. I used the below bash script to send 10 requests per second to the API gateway endpoint:
```
#!/bin/bash
while true
do date | tee -a curl-output.log
curl 2> /dev/null | tee -a curl-output.log
printf "\nResponse Code: " | tee -a curl-output.log
curl -sL -w "%{http_code} \\n" -o /dev/null | tee -a curl-output.log
printf "\n" | tee -a curl-output.log
sleep 0.1
done
```
During update, we can see that requests are sent to task after SIGTERM is received:
| Timestamp | Message |
| --- | --- |
| 1643464479304 | 10.0.190.40 - - [29/Jan/2022 13:54:39] "GET / HTTP/1.1" 200 - |
| 1643464479589 | 10.0.190.40 - - [29/Jan/2022 13:54:39] "GET / HTTP/1.1" 200 - |
| 1643464480115 | [2022-01-29 13:54:40,115] INFO in app: Caught SIGTERM, sleeping for 60 seconds |
| 1643464480314 | 10.0.190.40 - - [29/Jan/2022 13:54:40] "GET / HTTP/1.1" 200 - |
| 1643464483332 | 10.0.190.40 - - [29/Jan/2022 13:54:43] "GET / HTTP/1.1" 200 - |
| 1643464487383 | 10.0.190.40 - - [29/Jan/2022 13:54:47] "GET / HTTP/1.1" 200 - |
| 1643464494315 | 10.0.190.40 - - [29/Jan/2022 13:54:54] "GET / HTTP/1.1" 200 - |
| 1643464540166 | [2022-01-29 13:55:40,166] INFO in app: Done |
**Attachments**
None
Contributor guide
Research direction
The request concerns ECS service updates, Cloud Map deregistration, and task stopping; no repository files, tests, or implementation entry points are identified. Start with the linked AWS architecture example and the described API Gateway behavior; done would be a defined delay between deregistration and task stopping that prevents cached requests from reaching terminated tasks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws
- Domain
- api, cloud
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100