[DO NOT INSTALL] - Testing Heroku-redis migration

pull/1/head
hikariatama 2022-06-05 13:17:12 +00:00
parent dc7434e036
commit 18a0dac15d
7 changed files with 50 additions and 59 deletions

View File

@ -13,7 +13,7 @@
},
"addons": [
{
"plan": "heroku-postgresql"
"plan": "heroku-redis"
}
],
"buildpacks": [

View File

@ -15,14 +15,14 @@ import time
import asyncio
try:
import psycopg2
import redis
except ImportError as e:
if "DYNO" in os.environ:
raise e
POSTGRE_AVAILABLE = False
REDIS_AVAILABLE = False
else:
POSTGRE_AVAILABLE = True
REDIS_AVAILABLE = True
from typing import Any, Union
@ -50,7 +50,7 @@ class Database(dict):
_revisions = []
_assets = None
_me = None
_postgre = None
_redis = None
_saving_task = None
def __init__(self, client):
@ -60,59 +60,49 @@ class Database(dict):
def __repr__(self):
return object.__repr__(self)
def _postgre_save_sync(self):
self._postgre.execute(
"DELETE FROM hikka WHERE id = %s; INSERT INTO hikka (id, data) VALUES (%s, %s);",
(self._client._tg_id, self._client._tg_id, json.dumps(self)),
)
self._postgre.connection.commit()
def _redis_save_sync(self):
self._redis.set(str(self._client._tg_id), json.dumps(self, ensure_ascii=True))
async def postgre_force_save(self) -> bool:
"""Force save database to postgresql without waiting"""
if not self._postgre:
async def redis_force_save(self) -> bool:
"""Force save database to redis without waiting"""
if not self._redis:
return False
await utils.run_sync(self._postgre_save_sync)
logger.debug("Published db to PostgreSQL")
await utils.run_sync(self._redis_save_sync)
logger.debug("Published db to Redis")
return True
async def _postgre_save(self) -> bool:
"""Save database to postgresql"""
if not self._postgre:
async def _redis_save(self) -> bool:
"""Save database to redis"""
if not self._redis:
return False
await asyncio.sleep(5)
await utils.run_sync(self._postgre_save_sync)
await utils.run_sync(self._redis_save_sync)
logger.debug("Published db to PostgreSQL")
logger.debug("Published db to Redis")
self._saving_task = None
return True
async def postgre_init(self) -> bool:
"""Init postgresql database"""
if not POSTGRE_AVAILABLE:
logger.critical("Attempted to initialize postgresql database, but psycopg2 is not installed") # fmt: skip
async def redis_init(self) -> bool:
"""Init redis database"""
if not REDIS_AVAILABLE:
logger.critical("Attempted to initialize redis database, but it is not installed") # fmt: skip
return False
POSTGRE_URI = os.environ.get("DATABASE_URL") or main.get_config_key(
"postgre_uri"
)
REDIS_URI = os.environ.get("REDIS_URL") or main.get_config_key("redis_uri")
if not POSTGRE_URI:
if not REDIS_URI:
return False
conn = psycopg2.connect(POSTGRE_URI, sslmode="require")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS hikka (id integer, data text);")
self._postgre = cur
self._redis = redis.from_url(REDIS_URI)
async def init(self):
"""Asynchronous initialization unit"""
if os.environ.get("DATABASE_URL") or main.get_config_key("postgre_uri"):
await self.postgre_init()
if os.environ.get("REDIS_URL") or main.get_config_key("redis_uri"):
await self.redis_init()
self._db_path = os.path.join(DATA_DIR, f"config-{self._client._tg_id}.json")
self.read()
@ -163,15 +153,11 @@ class Database(dict):
def read(self):
"""Read database and stores it in self"""
if self._postgre:
if self._redis:
try:
self._postgre.execute(
"SELECT data FROM hikka WHERE id=%s;",
(self._client._tg_id,),
)
self.update(**json.loads(self._postgre.fetchall()[0][0]))
self.update(**json.loads(self._redis.get(str(self._client._tg_id))))
except Exception:
logger.exception("Error reading postgresql database")
logger.exception("Error reading redis database")
else:
return
@ -235,9 +221,9 @@ class Database(dict):
while len(self._revisions) > 15:
self._revisions.pop()
if self._postgre:
if self._redis:
if not self._saving_task:
self._saving_task = asyncio.ensure_future(self._postgre_save())
self._saving_task = asyncio.ensure_future(self._redis_save())
return True
try:

View File

@ -43,9 +43,9 @@ def publish(
)
if not any(
addon.plan.name.startswith("heroku-postgresql") for addon in app.addons()
addon.plan.name.startswith("heroku-redis") for addon in app.addons()
):
app.install_addon("heroku-postgresql")
app.install_addon("heroku-redis")
repo = get_repo()
url = app.git_url.replace("https://", f"https://api:{key}@")
@ -115,3 +115,8 @@ def init():
"""Will be run on every Heroku start"""
# Create repo if not found
get_repo()
app = get_app()[0]
if not any(
addon.plan.name.startswith("heroku-redis") for addon in app.addons()
):
app.install_addon("heroku-redis")

View File

@ -115,10 +115,10 @@ class PythonMod(loader.Module):
except Exception:
exc = format_exc().replace(self._phone, "📵")
if os.environ.get("DATABASE_URL"):
if os.environ.get("REDIS_URL"):
exc = exc.replace(
os.environ.get("DATABASE_URL"),
"postgre://**************************",
os.environ.get("REDIS_URL"),
"redis://**************************",
)
if os.environ.get("hikka_session"):
@ -142,10 +142,10 @@ class PythonMod(loader.Module):
)
ret = ret.replace(str(self._phone), "📵")
if os.environ.get("DATABASE_URL"):
if os.environ.get("REDIS_URL"):
ret = ret.replace(
os.environ.get("DATABASE_URL"),
"postgre://**************************",
os.environ.get("REDIS_URL"),
"redis://**************************",
)
if os.environ.get("hikka_session"):

View File

@ -340,10 +340,10 @@ class TestMod(loader.Module):
f'{hikka_token.split("_")[0]}_********************************',
)
if os.environ.get("DATABASE_URL"):
if os.environ.get("REDIS_URL"):
logs = logs.replace(
os.environ.get("DATABASE_URL"),
"postgre://**************************",
os.environ.get("REDIS_URL"),
"redis://**************************",
)
if os.environ.get("hikka_session"):

View File

@ -180,7 +180,7 @@ class UpdaterMod(loader.Module):
return
if "DYNO" in os.environ:
await self._db.postgre_force_save()
await self._db.redis_force_save()
app = heroku.get_app(api_token=main.hikka.api_token)[0]
app.restart()
return
@ -294,7 +294,7 @@ class UpdaterMod(loader.Module):
if "DYNO" in os.environ:
await utils.answer(msg_obj, self.strings("heroku_update"))
await self.process_restart_message(msg_obj)
await self._db.postgre_force_save()
await self._db.redis_force_save()
heroku.publish(api_token=main.hikka.api_token, create_new=False)
return

View File

@ -9,6 +9,6 @@ requests==2.27.1
aiogram==2.19
grapheme==0.6.0
heroku3==5.1.4
psycopg2-binary==2.9.3
redis==3.5.3
# Python 3.8+