import logging
import multiprocessing
from http.server import BaseHTTPRequestHandler, HTTPServer
from time import sleep
from modal import App, Image
logger = logging.getLogger(__name__)
image = Image.debian_slim()
app = App("mre-fork", image=image)
class SimpleHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
my_pid = multiprocessing.current_process().pid
self.wfile.write(f"Hello from forkserver process {my_pid}".encode())
def run_server():
server = HTTPServer(("0.0.0.0", 8081), SimpleHandler)
print("Server running on port 8081")
server.serve_forever()
@app.function(
min_containers=1,
)
async def mre():
multiprocessing.set_start_method("forkserver", force=True)
process = multiprocessing.Process(target=run_server)
process.start()
return process.pid
@app.local_entrypoint()
def main():
pid = mre.remote()
print(f"HTTP server spawned with forkserver method, PID: {pid}")
pid = mre.remote()
print(f"HTTP server spawned with forkserver method, PID: {pid}")
sleep(600)If you spawn processes across function calls, the processes seem to persist in the live container.
How to reproduce
- modal run
mre_fork.py - ssh to the container
ps auxorcurl localhost:8081you will see the process from first function call to respond