"Preparing to run: `python ./server.py` as root" but never runs

I am trying to host a relay server on Fly.io, for my peer-to-peer game. I used a Python script that I found on GitHub with some modifications. It runs well on my machine and gets the job done to some extent. I learned about Fly.io today and wanted to give it a shot, and I am not having the best time. Whenever I start the server, it prints out "Preparing to run: python ./server.py as root", but the script never runs. I know this, because when it runs it should print “Debug print” followed with “Listening on *:8080”. The weird part is that, these messages get printed when I restart the server, just before it gets shutdown. I would be very grateful to anyone who have any suggestions.

Logs:

2024-06-27T15:54:55.860 app[3d8dd629c97338] ams [info] 2024-06-27T15:54:55.860742285 [01J1D571M28ETRA8E7TV94WH5X:main] Running Firecracker v1.7.0

2024-06-27T15:54:56.186 app[3d8dd629c97338] ams [info] [ 0.267681] PCI: Fatal: No config space access function found

2024-06-27T15:54:56.465 app[3d8dd629c97338] ams [info] INFO Starting init (commit: ad092ccf)...

2024-06-27T15:54:56.493 app[3d8dd629c97338] ams [info] INFO Preparing to run: `python ./server.py` as root

2024-06-27T15:54:56.499 app[3d8dd629c97338] ams [info] INFO [fly api proxy] listening at /.fly/api

2024-06-27T15:54:56.506 app[3d8dd629c97338] ams [info] 2024/06/27 15:54:56 INFO SSH listening listen_address=[fdaa:9:78b0:a7b:39:4d7b:d829:2]:22 dns_server=[fdaa::3]:53

2024-06-27T15:54:56.522 runner[3d8dd629c97338] ams [info] Machine started in 751ms

server.py:

#!/usr/bin/python3
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from time import sleep

import sys



def address_to_string(address):
	ip, port = address
	return ':'.join([ip, str(port)])


class ServerProtocol(DatagramProtocol):

	def __init__(self):
		print("Debug print")
		self.active_sessions = {}
		self.registered_clients = {}

	def name_is_registered(self, name):
		return name in self.registered_clients

	def create_session(self, s_id, client_list):
		if s_id in self.active_sessions:
			print("Tried to create existing session")
			return

		self.active_sessions[s_id] = Session(s_id, client_list, self)


	def remove_session(self, s_id):
		try:
			del self.active_sessions[s_id]
		except KeyError:
			print("Tried to terminate non-existing session")


	def register_client(self, c_name, c_session, c_ip, c_port):
		if self.name_is_registered(c_name):
			print("Client %s is already registered." % [c_name])
			return
		if not c_session in self.active_sessions:
			print("Client registered for non-existing session")
		else:
			new_client = Client(c_name, c_session, c_ip, c_port)
			self.registered_clients[c_name] = new_client
			self.active_sessions[c_session].client_registered(new_client)

	def exchange_info(self, c_session):
		if not c_session in self.active_sessions:
			return
		self.active_sessions[c_session].exchange_peer_info()

	def client_checkout(self, name):
		try:
			del self.registered_clients[name]
		except KeyError:
			print("Tried to checkout unregistered client")

	def datagramReceived(self, datagram, address):
		"""Handle incoming datagram messages."""
		print(datagram)
		data_string = datagram.decode("utf-8")
		msg_type = data_string[:2]

		if msg_type == "rs":
			# register session
			c_ip, c_port = address
			self.transport.write(bytes('ok:'+str(c_port),"utf-8"), address)
			split = data_string.split(":")
			session = split[1]
			max_clients = split[2]
			self.create_session(session, max_clients)

		elif msg_type == "rc":
			# register client
			split = data_string.split(":")
			c_name = split[1]
			c_session = split[2]
			c_ip, c_port = address
			self.transport.write(bytes('ok:'+str(c_port),"utf-8"), address)
			self.register_client(c_name, c_session, c_ip, c_port)

		elif msg_type == "ep":
			# exchange peers
			split = data_string.split(":")
			c_session = split[1]
			self.exchange_info(c_session)

		elif msg_type == "cc":
			# checkout client
			split = data_string.split(":")
			c_name = split[1]
			self.client_checkout(c_name)



class Session:

	def __init__(self, session_id, max_clients, server):
		self.id = session_id
		self.client_max = max_clients
		self.server = server
		self.registered_clients = []


	def client_registered(self, client):
		if client in self.registered_clients: return
		# print("Client %c registered for Session %s" % client.name, self.id)
		self.registered_clients.append(client)
		if len(self.registered_clients) == int(self.client_max):
			sleep(5)
			print("waited for OK message to send, sending out info to peers")
			self.exchange_peer_info()

	def exchange_peer_info(self):
		for addressed_client in self.registered_clients:
			address_list = []
			for client in self.registered_clients:
				if not client.name == addressed_client.name:
					address_list.append(client.name + ":" + address_to_string((client.ip, client.port)))
			address_string = ",".join(address_list)
			message = bytes( "peers:" + address_string, "utf-8")
			self.server.transport.write(message, (addressed_client.ip, addressed_client.port))

		print("Peer info has been sent. Terminating Session")
		for client in self.registered_clients:
			self.server.client_checkout(client.name)
		self.server.remove_session(self.id)


class Client:

	def confirmation_received(self):
		self.received_peer_info = True

	def __init__(self, c_name, c_session, c_ip, c_port):
		self.name = c_name
		self.session_id = c_session
		self.ip = c_ip
		self.port = c_port
		self.received_peer_info = False

if __name__ == '__main__':
	port = 8080
	reactor.listenUDP(port, ServerProtocol())
	print('Listening on *:%d' % (port))
	reactor.run()

Dockerfile:

FROM python:3.12

COPY server.py .
COPY requirements.txt .

RUN pip install -r requirements.txt

ENTRYPOINT ["python", "./server.py"]

fly.toml:

app = 'nat-server-snowy-wildflower-8750'
primary_region = 'ams'

[build]

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

[[vm]]
  size = 'shared-cpu-1x'

From App not working to Questions / Help

Hi @brogolem35, shot in the dark: I wonder if your print statements are being buffered and then flushed on shutdown. In your shoes, I’d probably try using the Python logging module instead and see if your logs show up.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.