WebHost: re-introduce per-Room Locker (#3337)
This commit is contained in:
parent
cf34f125d6
commit
d3f4ee4994
|
@ -21,6 +21,7 @@ import Utils
|
||||||
|
|
||||||
from MultiServer import Context, server, auto_shutdown, ServerCommandProcessor, ClientMessageProcessor, load_server_cert
|
from MultiServer import Context, server, auto_shutdown, ServerCommandProcessor, ClientMessageProcessor, load_server_cert
|
||||||
from Utils import restricted_loads, cache_argsless
|
from Utils import restricted_loads, cache_argsless
|
||||||
|
from .locker import Locker
|
||||||
from .models import Command, GameDataPackage, Room, db
|
from .models import Command, GameDataPackage, Room, db
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,58 +232,61 @@ def run_server_process(name: str, ponyconfig: dict, static_server_data: dict,
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
async def start_room(room_id):
|
async def start_room(room_id):
|
||||||
try:
|
with Locker(f"RoomLocker {room_id}"):
|
||||||
logger = set_up_logging(room_id)
|
|
||||||
ctx = WebHostContext(static_server_data, logger)
|
|
||||||
ctx.load(room_id)
|
|
||||||
ctx.init_save()
|
|
||||||
try:
|
try:
|
||||||
ctx.server = websockets.serve(functools.partial(server, ctx=ctx), ctx.host, ctx.port, ssl=ssl_context)
|
logger = set_up_logging(room_id)
|
||||||
|
ctx = WebHostContext(static_server_data, logger)
|
||||||
|
ctx.load(room_id)
|
||||||
|
ctx.init_save()
|
||||||
|
try:
|
||||||
|
ctx.server = websockets.serve(
|
||||||
|
functools.partial(server, ctx=ctx), ctx.host, ctx.port, ssl=ssl_context)
|
||||||
|
|
||||||
await ctx.server
|
await ctx.server
|
||||||
except OSError: # likely port in use
|
except OSError: # likely port in use
|
||||||
ctx.server = websockets.serve(functools.partial(server, ctx=ctx), ctx.host, 0, ssl=ssl_context)
|
ctx.server = websockets.serve(
|
||||||
|
functools.partial(server, ctx=ctx), ctx.host, 0, ssl=ssl_context)
|
||||||
|
|
||||||
await ctx.server
|
await ctx.server
|
||||||
port = 0
|
port = 0
|
||||||
for wssocket in ctx.server.ws_server.sockets:
|
for wssocket in ctx.server.ws_server.sockets:
|
||||||
socketname = wssocket.getsockname()
|
socketname = wssocket.getsockname()
|
||||||
if wssocket.family == socket.AF_INET6:
|
if wssocket.family == socket.AF_INET6:
|
||||||
# Prefer IPv4, as most users seem to not have working ipv6 support
|
# Prefer IPv4, as most users seem to not have working ipv6 support
|
||||||
if not port:
|
if not port:
|
||||||
|
port = socketname[1]
|
||||||
|
elif wssocket.family == socket.AF_INET:
|
||||||
port = socketname[1]
|
port = socketname[1]
|
||||||
elif wssocket.family == socket.AF_INET:
|
if port:
|
||||||
port = socketname[1]
|
ctx.logger.info(f'Hosting game at {host}:{port}')
|
||||||
if port:
|
with db_session:
|
||||||
ctx.logger.info(f'Hosting game at {host}:{port}')
|
room = Room.get(id=ctx.room_id)
|
||||||
|
room.last_port = port
|
||||||
|
else:
|
||||||
|
ctx.logger.exception("Could not determine port. Likely hosting failure.")
|
||||||
with db_session:
|
with db_session:
|
||||||
room = Room.get(id=ctx.room_id)
|
ctx.auto_shutdown = Room.get(id=room_id).timeout
|
||||||
room.last_port = port
|
ctx.shutdown_task = asyncio.create_task(auto_shutdown(ctx, []))
|
||||||
else:
|
await ctx.shutdown_task
|
||||||
ctx.logger.exception("Could not determine port. Likely hosting failure.")
|
|
||||||
with db_session:
|
|
||||||
ctx.auto_shutdown = Room.get(id=room_id).timeout
|
|
||||||
ctx.shutdown_task = asyncio.create_task(auto_shutdown(ctx, []))
|
|
||||||
await ctx.shutdown_task
|
|
||||||
|
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
with db_session:
|
with db_session:
|
||||||
room = Room.get(id=room_id)
|
|
||||||
room.last_port = -1
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
with (db_session):
|
|
||||||
# ensure the Room does not spin up again on its own, minute of safety buffer
|
|
||||||
room = Room.get(id=room_id)
|
room = Room.get(id=room_id)
|
||||||
room.last_activity = datetime.datetime.utcnow() - \
|
room.last_port = -1
|
||||||
datetime.timedelta(minutes=1, seconds=room.timeout)
|
raise
|
||||||
logging.info(f"Shutting down room {room_id} on {name}.")
|
|
||||||
finally:
|
finally:
|
||||||
await asyncio.sleep(5)
|
try:
|
||||||
rooms_shutting_down.put(room_id)
|
with (db_session):
|
||||||
|
# ensure the Room does not spin up again on its own, minute of safety buffer
|
||||||
|
room = Room.get(id=room_id)
|
||||||
|
room.last_activity = datetime.datetime.utcnow() - \
|
||||||
|
datetime.timedelta(minutes=1, seconds=room.timeout)
|
||||||
|
logging.info(f"Shutting down room {room_id} on {name}.")
|
||||||
|
finally:
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
rooms_shutting_down.put(room_id)
|
||||||
|
|
||||||
class Starter(threading.Thread):
|
class Starter(threading.Thread):
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
Loading…
Reference in New Issue