Skip to content
This repository was archived by the owner on Dec 16, 2021. It is now read-only.

Commit f95ab96

Browse files
varunbpatilAndres Martinez GotorVarun Basavaraj Patil
authored
Fix python runtime deadlock due to multithreading + fork (#97)
* Fix python runtime deadlock due to multithreading + fork Drop support for Python2.7 runtime because it has reached End Of Life and also because "spawn" and "forkserver" multiprocessing contexts are not supported in Python 2.7 which are required to fix the deadlock. * Update images * Display K8s objects on test failure. Co-authored-by: Andres Martinez Gotor <[email protected]> Co-authored-by: Varun Basavaraj Patil <[email protected]>
1 parent 60a58bf commit f95ab96

16 files changed

+320
-191
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ defaults: &defaults
1010
run_test: &run_test
1111
steps:
1212
- checkout
13+
- run: echo "export GIT_SHA1=${CIRCLE_SHA1}" >> $BASH_ENV
1314
- run: |
1415
# Determine if running the tests are necessary
1516
if [[ -n "$CIRCLE_PULL_REQUEST" ]]; then

script/integration-tests.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,20 @@ kubectl rollout status -n kubeless deployment/kubeless-controller-manager
3636

3737
make -C ${ROOT_DIR}/${target} deploy
3838
make -C ${ROOT_DIR}/${target} test
39+
40+
exit_code=$?
41+
42+
# Just showing remaining k8s objects
43+
kubectl get all --all-namespaces
44+
45+
if [ ${exit_code} -ne 0 -o -n "${TRAVIS_DUMP_LOGS}" ]; then
46+
echo "INFO: Build ERRORed, dumping logs: ##"
47+
for ns in kubeless default; do
48+
echo "### LOGs: namespace: ${ns} ###"
49+
kubectl get pod -n ${ns} -oname|xargs -I@ sh -xc "kubectl logs -n ${ns} @|sed 's|^|@: |'"
50+
done
51+
echo "INFO: Description"
52+
kubectl describe pod -l created-by=kubeless
53+
fi
54+
[ ${exit_code} -eq 0 ] && echo "INFO: $0: SUCCESS" || echo "ERROR: $0: FAILED"
55+
exit ${exit_code}

stable/python/Dockerfile.2.7

Lines changed: 0 additions & 14 deletions
This file was deleted.

stable/python/Dockerfile.3.6

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ RUN python ./get-pip.py
1717
RUN pip install bottle==0.12.13 cherrypy==8.9.1 wsgi-request-logger prometheus_client
1818

1919
WORKDIR /
20-
ADD kubeless.py .
20+
ADD _kubeless.py .
2121

2222
USER 1000
2323

2424
ENV PYTHONUNBUFFERED 1
25-
CMD ["python", "/kubeless.py"]
25+
CMD ["python", "/_kubeless.py"]

stable/python/Dockerfile.3.7

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ RUN python ./get-pip.py
1717
RUN pip install bottle==0.12.13 cherrypy==8.9.1 wsgi-request-logger prometheus_client
1818

1919
WORKDIR /
20-
ADD kubeless.py .
20+
ADD _kubeless.py .
2121

2222
USER 1000
2323

2424
ENV PYTHONUNBUFFERED 1
25-
CMD ["python", "/kubeless.py"]
25+
CMD ["python", "/_kubeless.py"]

stable/python/Makefile

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,73 @@
1+
GIT_SHA1 ?= master
2+
BASE_URL := https://raw.githubusercontent.com/kubeless/runtimes/$(GIT_SHA1)
13

2-
build2.7:
3-
docker build --pull --no-cache -t kubeless/python:2.7$$RUNTIME_TAG_MODIFIER -f Dockerfile.2.7 .
4+
# Wait until the Pod is in ready state. Without a readinessProbe it is not possible to
5+
# tell exactly when the Pod is ready to accept requests. So, adding additional sleep
6+
# (default = 2 seconds).
7+
define rollout-status
8+
kubectl rollout status deployment/$(patsubst %-verify,%,$1) && sleep $(if $2,$2,2)
9+
endef
410

511
build3.6:
612
docker build --pull --no-cache -t kubeless/python:3.6$$RUNTIME_TAG_MODIFIER -f Dockerfile.3.6 .
713

814
build3.7:
915
docker build --pull --no-cache -t kubeless/python:3.7$$RUNTIME_TAG_MODIFIER -f Dockerfile.3.7 .
1016

11-
push2.7:
12-
docker push kubeless/python:2.7$$RUNTIME_TAG_MODIFIER
13-
1417
push3.6:
1518
docker push kubeless/python:3.6$$RUNTIME_TAG_MODIFIER
1619

1720
push3.7:
1821
docker push kubeless/python:3.7$$RUNTIME_TAG_MODIFIER
1922

2023
# Mandatory jobs
21-
build-all: build2.7 build3.6 build3.7
22-
push-all: push2.7 push3.6 push3.7
24+
build-all: build3.6 build3.7
25+
push-all: push3.6 push3.7
2326

2427
# Testing jobs
25-
deploy: get-python get-python-deps get-python-custom-port get-python-36 get-python-37 get-python-url-deps scheduled-get-python timeout-python get-python-secrets post-python post-python-custom-port custom-get-python
26-
test: get-python-verify get-python-deps-verify get-python-custom-port-verify get-python-36-verify get-python-37-verify get-python-url-deps-verify scheduled-get-python-verify timeout-python-verify get-python-secrets-verify custom-get-python-verify post-python-verify post-python-custom-port-verify
27-
28-
get-python:
29-
kubeless function deploy get-python --runtime python2.7 --handler helloget.foo --from-file examples/helloget.py
30-
31-
get-python-verify:
32-
kubectl rollout status deployment/get-python && sleep 2
33-
kubeless function call get-python |egrep hello.world
34-
kubeless function top --function get-python --out yaml |egrep total_calls.*[1-100000]
28+
deploy: get-python-deps get-python-custom-port get-python-36 get-python-37 get-python-url-deps scheduled-get-python timeout-python get-python-secrets post-python post-python-custom-port custom-get-python python-preload
29+
test: get-python-deps-verify get-python-custom-port-verify get-python-36-verify get-python-37-verify get-python-url-deps-verify scheduled-get-python-verify timeout-python-verify get-python-secrets-verify custom-get-python-verify post-python-verify post-python-custom-port-verify python-preload-verify
3530

3631
get-python-deps:
37-
cd examples && zip hellowithdeps.zip hellowithdeps.py hellowithdepshelper.py && cd ..
38-
kubeless function deploy get-python-deps --runtime python2.7 --handler hellowithdeps.foo --from-file examples/hellowithdeps.zip --dependencies examples/requirements.txt
32+
cd examples && zip hellowithdeps.zip hellowithdeps.py hellowithdepshelper.py
33+
kubeless function deploy get-python-deps --runtime python3.6 --handler hellowithdeps.foo --from-file examples/hellowithdeps.zip --dependencies examples/requirements.txt
3934

4035
get-python-deps-verify:
41-
kubectl rollout status deployment/get-python-deps && sleep 2
36+
$(call rollout-status,$@,5)
4237
kubeless function call get-python-deps |egrep Google
4338

4439
get-python-custom-port:
45-
kubeless function deploy get-python-custom-port --runtime python2.7 --handler helloget.foo --from-file examples/helloget.py --port 8081
40+
kubeless function deploy get-python-custom-port --runtime python3.6 --handler helloget.foo --from-file examples/helloget.py --port 8081
4641

4742
get-python-custom-port-verify:
48-
kubectl rollout status deployment/get-python-custom-port && sleep 2
43+
$(call rollout-status,$@)
4944
kubectl get svc get-python-custom-port -o yaml | grep 'targetPort: 8081'
5045
kubeless function call get-python-custom-port |egrep hello.world
5146

5247
get-python-36:
5348
kubeless function deploy get-python-36 --runtime python3.6 --handler helloget.foo --from-file examples/helloget.py
5449

5550
get-python-36-verify:
56-
kubectl rollout status deployment/get-python-36 && sleep 2
51+
$(call rollout-status,$@)
5752
kubeless function call get-python-36 |egrep hello.world
5853

5954
get-python-37:
6055
kubeless function deploy get-python-37 --runtime python3.7 --handler helloget.foo --from-file examples/helloget.py
6156

6257
get-python-37-verify:
63-
kubectl rollout status deployment/get-python-37 && sleep 2
58+
$(call rollout-status,$@)
6459
kubeless function call get-python-37 |egrep hello.world
6560

6661
get-python-url-deps:
67-
kubeless function deploy get-python-url-deps --runtime python2.7 --handler helloget.foo --from-file https://raw.githubusercontent.com/kubeless/kubeless/v1.0.0-alpha.1/examples/python/hellowithdeps.py --dependencies https://raw.githubusercontent.com/kubeless/kubeless/v1.0.0-alpha.1/examples/python/requirements.txt
62+
cd examples && zip hellowithdeps.zip hellowithdeps.py hellowithdepshelper.py
63+
kubeless function deploy get-python-url-deps --runtime python3.6 --handler hellowithdeps.foo --from-file examples/hellowithdeps.zip --dependencies $(BASE_URL)/stable/python/examples/requirements.txt
6864

6965
get-python-url-deps-verify:
70-
kubectl rollout status deployment/get-python-url-deps && sleep 2
66+
$(call rollout-status,$@)
7167
kubeless function call get-python-url-deps |egrep Google
7268

7369
scheduled-get-python:
74-
kubeless function deploy scheduled-get-python --schedule "* * * * *" --runtime python2.7 --handler helloget.foo --from-file examples/helloget.py
70+
kubeless function deploy scheduled-get-python --schedule "* * * * *" --runtime python3.6 --handler helloget.foo --from-file examples/helloget.py
7571

7672
scheduled-get-python-verify:
7773
number="1"; \
@@ -92,35 +88,35 @@ scheduled-get-python-verify:
9288
timeout-python:
9389
$(eval TMPDIR := $(shell mktemp -d))
9490
printf 'def foo(event, context):\n%4swhile 1: pass\n%4sreturn "hello world"\n' > $(TMPDIR)/hello-loop.py
95-
kubeless function deploy timeout-python --runtime python2.7 --handler helloget.foo --from-file $(TMPDIR)/hello-loop.py --timeout 3
91+
kubeless function deploy timeout-python --runtime python3.6 --handler helloget.foo --from-file $(TMPDIR)/hello-loop.py --timeout 3
9692
rm -rf $(TMPDIR)
9793

9894
timeout-python-verify:
99-
kubectl rollout status deployment/timeout-python && sleep 2
95+
$(call rollout-status,$@)
10096
$(eval MSG := $(shell kubeless function call timeout-python 2>&1 || true))
10197
echo $(MSG) | egrep Request.timeout.exceeded
10298

10399
get-python-secrets:
104100
kubectl create secret generic test-secret --from-literal=key=MY_KEY || true
105-
kubeless function deploy get-python-secrets --runtime python2.7 --handler helloget.foo --from-file examples/helloget.py --secrets test-secret
101+
kubeless function deploy get-python-secrets --runtime python3.6 --handler helloget.foo --from-file examples/helloget.py --secrets test-secret
106102

107103
get-python-secrets-verify:
108-
kubectl rollout status deployment/get-python-secrets && sleep 2
104+
$(call rollout-status,$@)
109105
$(eval pod := $(shell kubectl get pod -l function=get-python-secrets -o go-template -o custom-columns=:metadata.name --no-headers=true))
110106
kubectl exec -it $(pod) cat /test-secret/key | egrep "MY_KEY"
111107

112108
custom-get-python:
113109
kubeless function deploy --runtime-image kubeless/get-python-example@sha256:6a14400f14e26d46a971445b7a850af533fe40cb75a67297283bdf536e09ca5e custom-get-python
114110

115111
custom-get-python-verify:
116-
kubectl rollout status deployment/custom-get-python && sleep 2
112+
$(call rollout-status,$@)
117113
kubeless function call custom-get-python |egrep hello.world
118114

119115
post-python:
120-
kubeless function deploy post-python --runtime python2.7 --handler hellowithdata.handler --from-file examples/hellowithdata.py
116+
kubeless function deploy post-python --runtime python3.6 --handler hellowithdata.handler --from-file examples/hellowithdata.py
121117

122118
post-python-verify:
123-
kubectl rollout status deployment/post-python && sleep 2
119+
$(call rollout-status,$@)
124120
kubeless function call post-python --data '{"it-s": "alive"}'|egrep "it.*alive"
125121
# Verify event context
126122
logs=`kubectl logs --tail=1000 -l function=post-python`; \
@@ -131,9 +127,17 @@ post-python-verify:
131127
echo $$logs | grep -q "event-id.*"
132128

133129
post-python-custom-port:
134-
kubeless function deploy post-python-custom-port --runtime python2.7 --handler hellowithdata.handler --from-file examples/hellowithdata.py --port 8081
130+
kubeless function deploy post-python-custom-port --runtime python3.6 --handler hellowithdata.handler --from-file examples/hellowithdata.py --port 8081
135131

136132
post-python-custom-port-verify:
137-
kubectl rollout status deployment/post-python-custom-port && sleep 2
133+
$(call rollout-status,$@)
138134
kubectl get svc post-python-custom-port -o yaml | grep 'targetPort: 8081'
139135
kubeless function call post-python-custom-port --data '{"it-s": "alive"}'|egrep "it.*alive"
136+
137+
python-preload:
138+
cd examples && zip preload.zip preload.py preloadhelper.py
139+
kubeless function deploy python-preload --runtime python3.6 --handler preload.handler --from-file examples/preload.zip --timeout 3
140+
141+
python-preload-verify:
142+
$(call rollout-status,$@,10)
143+
kubeless function call python-preload |egrep hello.world

stable/python/OWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
- andresmgot
2+
- varunbpatil

0 commit comments

Comments
 (0)