Skip to content

Commit 22c2e28

Browse files
committed
Use multiprocess for dev db check so it can be terminated
1 parent 5147fc2 commit 22c2e28

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

plain-dev/plain/dev/cli.py

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import importlib
22
import json
3+
import multiprocessing
34
import os
45
import platform
56
import signal
67
import subprocess
78
import sys
8-
import threading
99
import time
1010
import tomllib
1111
from importlib.metadata import entry_points
@@ -223,21 +223,16 @@ def run(self):
223223
# If plain.models is installed (common) then we
224224
# will do a couple extra things before starting all of the app-related
225225
# processes (this way they don't all have to db-wait or anything)
226+
process = None
226227
if find_spec("plain.models") is not None:
227228
# Use a custom signal to tell the main thread to add
228229
# the app processes once the db is ready
229230
signal.signal(signal.SIGUSR1, self.start_app)
230231

231-
def _thread(env):
232-
subprocess.run(["plain", "models", "db-wait"], env=env, check=True)
233-
subprocess.run(["plain", "migrate", "--backup"], env=env, check=True)
234-
# preflight with db?
235-
os.kill(os.getpid(), signal.SIGUSR1)
236-
237-
thread = threading.Thread(
238-
target=_thread, daemon=True, args=(self.plain_env,)
232+
process = multiprocessing.Process(
233+
target=_process_task, args=(self.plain_env,)
239234
)
240-
thread.start()
235+
process.start()
241236
else:
242237
# Start the app processes immediately
243238
self.start_app(None, None)
@@ -253,6 +248,14 @@ def _thread(env):
253248
if services_pid:
254249
services_pid.rm()
255250

251+
# Make sure the process is terminated if it is still running
252+
if process and process.is_alive():
253+
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
254+
process.join(timeout=3)
255+
if process.is_alive():
256+
os.killpg(os.getpgid(process.pid), signal.SIGKILL)
257+
process.join()
258+
256259
return self.poncho.returncode
257260

258261
def start_app(self, signum, frame):
@@ -439,3 +442,16 @@ def add_pyproject_run(self):
439442
**data.get("env", {}),
440443
}
441444
self.poncho.add_process(name, data["cmd"], env=env)
445+
446+
447+
def _process_task(env):
448+
# Make this process the leader of a new group which can be killed together if it doesn't finish
449+
os.setsid()
450+
451+
subprocess.run(["plain", "models", "db-wait"], env=env, check=True)
452+
subprocess.run(["plain", "migrate", "--backup"], env=env, check=True)
453+
454+
# preflight with db?
455+
456+
# Send SIGUSR1 to the parent process so the parent's handler is invoked
457+
os.kill(os.getppid(), signal.SIGUSR1)

0 commit comments

Comments
 (0)