add guild.region = null consistency checker

as soon as a voice region is added, we should move all guilds to it. or
if there are any guilds with a NULL region, we select one at random.

region being NULL causes the client to be unable to change it, so..

 - channels: fix update handlers for guild channels
This commit is contained in:
Luna 2019-03-04 03:00:46 -03:00
parent 336f3a6eaf
commit ad7f93b40a
3 changed files with 49 additions and 5 deletions

View File

@ -19,12 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncpg import asyncpg
from quart import Blueprint, jsonify, current_app as app, request from quart import Blueprint, jsonify, current_app as app, request
from logbook import Logger
from litecord.auth import admin_check from litecord.auth import admin_check
from litecord.schemas import validate from litecord.schemas import validate
from litecord.admin_schemas import VOICE_SERVER, VOICE_REGION from litecord.admin_schemas import VOICE_SERVER, VOICE_REGION
from litecord.errors import BadRequest from litecord.errors import BadRequest
log = Logger(__name__)
bp = Blueprint('voice_admin', __name__) bp = Blueprint('voice_admin', __name__)
@ -49,9 +51,20 @@ async def insert_new_region():
VALUES ($1, $2, $3, $4, $5) VALUES ($1, $2, $3, $4, $5)
""", j['id'], j['name'], j['vip'], j['deprecated'], j['custom']) """, j['id'], j['name'], j['vip'], j['deprecated'], j['custom'])
return jsonify( regions = await app.storage.all_voice_regions()
await app.storage.all_voice_regions() region_count = len(regions)
)
# if region count is 1, this is the first region to be created,
# so we should update all guilds to that region
if region_count == 1:
res = await app.db.execute("""
UPDATE guilds
SET region = $1
""", j['id'])
log.info('updating guilds to first voice region: {}', res)
return jsonify(regions)
@bp.route('/regions/<region>/servers', methods=['PUT']) @bp.route('/regions/<region>/servers', methods=['PUT'])
@ -86,3 +99,31 @@ async def deprecate_region(region):
""", region) """, region)
return '', 204 return '', 204
async def guild_region_check(app_):
"""Check all guilds for voice region inconsistencies.
Since the voice migration caused all guilds.region columns
to become NULL, we need to remove such NULLs if we have more
than one region setup.
"""
regions = await app_.storage.all_voice_regions()
if not regions:
log.info('region check: no regions to move guilds to')
return
res = await app_.db.execute("""
UPDATE guilds
SET region = (
SELECT id
FROM voice_regions
OFFSET floor(random()*$1)
LIMIT 1
)
WHERE region = NULL
""", len(regions))
log.info('region check: updating guild.region=null: {!r}', res)

View File

@ -393,7 +393,7 @@ async def _common_guild_chan(channel_id, j: dict):
""", j[field], channel_id) """, j[field], channel_id)
async def _update_text_channel(channel_id: int, j: dict): async def _update_text_channel(channel_id: int, j: dict, _user_id: int):
# first do the specific ones related to guild_text_channels # first do the specific ones related to guild_text_channels
for field in [field for field in j.keys() for field in [field for field in j.keys()
if field in ('topic', 'rate_limit_per_user')]: if field in ('topic', 'rate_limit_per_user')]:
@ -406,7 +406,7 @@ async def _update_text_channel(channel_id: int, j: dict):
await _common_guild_chan(channel_id, j) await _common_guild_chan(channel_id, j)
async def _update_voice_channel(channel_id: int, j: dict): async def _update_voice_channel(channel_id: int, j: dict, _user_id: int):
# first do the specific ones in guild_voice_channels # first do the specific ones in guild_voice_channels
for field in [field for field in j.keys() for field in [field for field in j.keys()
if field in ('bitrate', 'user_limit')]: if field in ('bitrate', 'user_limit')]:

3
run.py
View File

@ -60,6 +60,8 @@ from litecord.blueprints.admin_api import (
voice as voice_admin voice as voice_admin
) )
from litecord.blueprints.admin_api.voice import guild_region_check
from litecord.ratelimits.handler import ratelimit_handler from litecord.ratelimits.handler import ratelimit_handler
from litecord.ratelimits.main import RatelimitManager from litecord.ratelimits.main import RatelimitManager
@ -298,6 +300,7 @@ async def post_app_start(app_):
# we'll need to start a billing job # we'll need to start a billing job
app_.sched.spawn(payment_job(app_)) app_.sched.spawn(payment_job(app_))
app_.sched.spawn(api_index(app_)) app_.sched.spawn(api_index(app_))
app_.sched.spawn(guild_region_check(app_))
def start_websocket(host, port, ws_handler) -> asyncio.Future: def start_websocket(host, port, ws_handler) -> asyncio.Future: