WebHost: cleanup generate and hopefully fix SQL concurrency problems
This commit is contained in:
parent
449bc93307
commit
74b19dc1f5
|
@ -154,8 +154,10 @@ def autogen(config: dict):
|
||||||
while 1:
|
while 1:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
with db_session:
|
with db_session:
|
||||||
|
# for update locks the database row(s) during transaction, preventing writes from elsewhere
|
||||||
to_start = select(
|
to_start = select(
|
||||||
generation for generation in Generation if generation.state == STATE_QUEUED)
|
generation for generation in Generation
|
||||||
|
if generation.state == STATE_QUEUED).for_update()
|
||||||
for generation in to_start:
|
for generation in to_start:
|
||||||
launch_generator(generator_pool, generation)
|
launch_generator(generator_pool, generation)
|
||||||
except AlreadyRunningException:
|
except AlreadyRunningException:
|
||||||
|
|
|
@ -4,7 +4,7 @@ import random
|
||||||
import json
|
import json
|
||||||
import zipfile
|
import zipfile
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import Dict, Optional as TypeOptional
|
from typing import Dict, Optional, Any
|
||||||
from Utils import __version__
|
from Utils import __version__
|
||||||
|
|
||||||
from flask import request, flash, redirect, url_for, session, render_template
|
from flask import request, flash, redirect, url_for, session, render_template
|
||||||
|
@ -15,7 +15,7 @@ from BaseClasses import seeddigits, get_seed
|
||||||
from Generate import handle_name, PlandoSettings
|
from Generate import handle_name, PlandoSettings
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
from .models import *
|
from .models import Generation, STATE_ERROR, STATE_QUEUED, commit, db_session, Seed, UUID
|
||||||
from WebHostLib import app
|
from WebHostLib import app
|
||||||
from .check import get_yaml_data, roll_options
|
from .check import get_yaml_data, roll_options
|
||||||
from .upload import upload_zip_to_db
|
from .upload import upload_zip_to_db
|
||||||
|
@ -30,16 +30,15 @@ def get_meta(options_source: dict) -> dict:
|
||||||
}
|
}
|
||||||
plando_options -= {""}
|
plando_options -= {""}
|
||||||
|
|
||||||
meta = {
|
server_options = {
|
||||||
"hint_cost": int(options_source.get("hint_cost", 10)),
|
"hint_cost": int(options_source.get("hint_cost", 10)),
|
||||||
"forfeit_mode": options_source.get("forfeit_mode", "goal"),
|
"forfeit_mode": options_source.get("forfeit_mode", "goal"),
|
||||||
"remaining_mode": options_source.get("remaining_mode", "disabled"),
|
"remaining_mode": options_source.get("remaining_mode", "disabled"),
|
||||||
"collect_mode": options_source.get("collect_mode", "disabled"),
|
"collect_mode": options_source.get("collect_mode", "disabled"),
|
||||||
"item_cheat": bool(int(options_source.get("item_cheat", 1))),
|
"item_cheat": bool(int(options_source.get("item_cheat", 1))),
|
||||||
"server_password": options_source.get("server_password", None),
|
"server_password": options_source.get("server_password", None),
|
||||||
"plando_options": list(plando_options)
|
|
||||||
}
|
}
|
||||||
return meta
|
return {"server_options": server_options, "plando_options": list(plando_options)}
|
||||||
|
|
||||||
|
|
||||||
@app.route('/generate', methods=['GET', 'POST'])
|
@app.route('/generate', methods=['GET', 'POST'])
|
||||||
|
@ -60,13 +59,13 @@ def generate(race=False):
|
||||||
results, gen_options = roll_options(options, meta["plando_options"])
|
results, gen_options = roll_options(options, meta["plando_options"])
|
||||||
|
|
||||||
if race:
|
if race:
|
||||||
meta["item_cheat"] = False
|
meta["server_options"]["item_cheat"] = False
|
||||||
meta["remaining_mode"] = "disabled"
|
meta["server_options"]["remaining_mode"] = "disabled"
|
||||||
|
|
||||||
if any(type(result) == str for result in results.values()):
|
if any(type(result) == str for result in results.values()):
|
||||||
return render_template("checkResult.html", results=results)
|
return render_template("checkResult.html", results=results)
|
||||||
elif len(gen_options) > app.config["MAX_ROLL"]:
|
elif len(gen_options) > app.config["MAX_ROLL"]:
|
||||||
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players for now. "
|
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players. "
|
||||||
f"If you have a larger group, please generate it yourself and upload it.")
|
f"If you have a larger group, please generate it yourself and upload it.")
|
||||||
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
|
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
|
||||||
gen = Generation(
|
gen = Generation(
|
||||||
|
@ -92,23 +91,22 @@ def generate(race=False):
|
||||||
return render_template("generate.html", race=race, version=__version__)
|
return render_template("generate.html", race=race, version=__version__)
|
||||||
|
|
||||||
|
|
||||||
def gen_game(gen_options, meta: TypeOptional[Dict[str, object]] = None, owner=None, sid=None):
|
def gen_game(gen_options, meta: Optional[Dict[str, Any]] = None, owner=None, sid=None):
|
||||||
if not meta:
|
if not meta:
|
||||||
meta: Dict[str, object] = {}
|
meta: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
meta.setdefault("server_options", {}).setdefault("hint_cost", 10)
|
||||||
|
race = meta.setdefault("race", False)
|
||||||
|
|
||||||
meta.setdefault("hint_cost", 10)
|
|
||||||
race = meta.get("race", False)
|
|
||||||
del (meta["race"])
|
|
||||||
plando_options = meta.get("plando", {"bosses", "items", "connections", "texts"})
|
|
||||||
del (meta["plando_options"])
|
|
||||||
try:
|
try:
|
||||||
target = tempfile.TemporaryDirectory()
|
target = tempfile.TemporaryDirectory()
|
||||||
playercount = len(gen_options)
|
playercount = len(gen_options)
|
||||||
seed = get_seed()
|
seed = get_seed()
|
||||||
random.seed(seed)
|
|
||||||
|
|
||||||
if race:
|
if race:
|
||||||
random.seed() # reset to time-based random source
|
random.seed() # use time-based random source
|
||||||
|
else:
|
||||||
|
random.seed(seed)
|
||||||
|
|
||||||
seedname = "W" + (f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits))
|
seedname = "W" + (f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits))
|
||||||
|
|
||||||
|
@ -120,7 +118,8 @@ def gen_game(gen_options, meta: TypeOptional[Dict[str, object]] = None, owner=No
|
||||||
erargs.outputname = seedname
|
erargs.outputname = seedname
|
||||||
erargs.outputpath = target.name
|
erargs.outputpath = target.name
|
||||||
erargs.teams = 1
|
erargs.teams = 1
|
||||||
erargs.plando_options = PlandoSettings.from_set(plando_options)
|
erargs.plando_options = PlandoSettings.from_set(meta.setdefault("plando_options",
|
||||||
|
{"bosses", "items", "connections", "texts"}))
|
||||||
|
|
||||||
name_counter = Counter()
|
name_counter = Counter()
|
||||||
for player, (playerfile, settings) in enumerate(gen_options.items(), 1):
|
for player, (playerfile, settings) in enumerate(gen_options.items(), 1):
|
||||||
|
@ -136,7 +135,7 @@ def gen_game(gen_options, meta: TypeOptional[Dict[str, object]] = None, owner=No
|
||||||
erargs.name[player] = handle_name(erargs.name[player], player, name_counter)
|
erargs.name[player] = handle_name(erargs.name[player], player, name_counter)
|
||||||
if len(set(erargs.name.values())) != len(erargs.name):
|
if len(set(erargs.name.values())) != len(erargs.name):
|
||||||
raise Exception(f"Names have to be unique. Names: {Counter(erargs.name.values())}")
|
raise Exception(f"Names have to be unique. Names: {Counter(erargs.name.values())}")
|
||||||
ERmain(erargs, seed, baked_server_options=meta)
|
ERmain(erargs, seed, baked_server_options=meta["server_options"])
|
||||||
|
|
||||||
return upload_to_db(target.name, sid, owner, race)
|
return upload_to_db(target.name, sid, owner, race)
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
|
@ -148,7 +147,6 @@ def gen_game(gen_options, meta: TypeOptional[Dict[str, object]] = None, owner=No
|
||||||
meta = json.loads(gen.meta)
|
meta = json.loads(gen.meta)
|
||||||
meta["error"] = (e.__class__.__name__ + ": " + str(e))
|
meta["error"] = (e.__class__.__name__ + ": " + str(e))
|
||||||
gen.meta = json.dumps(meta)
|
gen.meta = json.dumps(meta)
|
||||||
|
|
||||||
commit()
|
commit()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue