-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add schedule entrance and job name para #107
base: pre-release/v0.3.0
Are you sure you want to change the base?
Changes from 2 commits
ef16d2d
dc4f483
f60b629
07ffd53
885cde7
978d4a1
ce18442
48dfc10
f07370f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import os | ||
import sys | ||
from datetime import datetime | ||
|
||
import click | ||
from apscheduler.schedulers.blocking import BlockingScheduler | ||
|
||
from indexer.schedule_jobs.aggregates_jobs import aggregates_yesterday_job, parse_crontab | ||
|
||
|
||
@click.command(context_settings=dict(help_option_names=["-h", "--help"])) | ||
@click.option( | ||
"-cn", | ||
"--chain-name", | ||
default=None, | ||
show_default=True, | ||
type=str, | ||
help="The chain name of the chain to aggregate data for", | ||
envvar="CHAIN_NAME", | ||
) | ||
@click.option( | ||
"-jn", | ||
"--job-name", | ||
default=None, | ||
show_default=True, | ||
type=str, | ||
help="Job list to aggregate data for", | ||
envvar="JOB_NAME", | ||
) | ||
@click.option( | ||
"-pg", | ||
"--postgres-url", | ||
type=str, | ||
required=True, | ||
envvar="POSTGRES_URL", | ||
help="The required postgres connection url." "e.g. postgresql+psycopg2://postgres:[email protected]:5432/ethereum", | ||
) | ||
@click.option( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest not to add this. You can assume you have token price table in postgres-url There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
"-du", | ||
"--dblink-url", | ||
default=None, | ||
show_default=True, | ||
type=str, | ||
envvar="DBLINK_URL", | ||
help="dblink to take token price, maybe moved to other replace later", | ||
) | ||
@click.option( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can only run one job at a time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but it has changed now. |
||
"-st", | ||
"--schedule-time", | ||
default="0 1 * * *", | ||
show_default=True, | ||
type=str, | ||
envvar="SCHEDULE_TIME", | ||
help="schedule time by crontab expression: default: 0 1 * * *", | ||
) | ||
def schedule(schedule_time, job_name, chain_name, postgres_url, dblink_url) -> None: | ||
sys.stdout = os.fdopen(sys.stdout.fileno(), "w", buffering=1) # Line-buffered stdout | ||
sys.stderr = os.fdopen(sys.stderr.fileno(), "w", buffering=1) # Line-buffered stderr | ||
|
||
parsed_crontab = parse_crontab(schedule_time) | ||
minute = parsed_crontab["minute"] | ||
hour = parsed_crontab["hour"] | ||
|
||
day = parsed_crontab["day"] | ||
month = parsed_crontab["month"] | ||
day_of_week = parsed_crontab["day_of_week"] | ||
|
||
scheduler = BlockingScheduler() | ||
job_args = (chain_name, job_name, postgres_url, dblink_url) | ||
scheduler.add_job( | ||
aggregates_yesterday_job, | ||
"cron", | ||
hour=hour, | ||
minute=minute, | ||
day=day, | ||
month=month, | ||
day_of_week=day_of_week, | ||
args=job_args, | ||
) | ||
|
||
scheduler.start() | ||
# current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | ||
# print(f'Job started {current_time}, schedule time is {hour}:{minute} daily') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import time | ||
|
||
from sqlalchemy import text | ||
|
||
|
||
class InitializationJob: | ||
def __init__(self, **kwargs): | ||
config = kwargs["config"] | ||
job_list = kwargs["job_list"] | ||
self.job_list = job_list.get_initialization_jobs() | ||
|
||
self.db_service = config["db_service"] | ||
self.dblink_url = config["dblink_url"] | ||
|
||
def init_token_price(self): | ||
token_price_sql_template = """ | ||
CREATE EXTENSION if not exists dblink; | ||
|
||
DELETE FROM token_price WHERE timestamp >= :start_date; | ||
|
||
INSERT INTO token_price | ||
SELECT * FROM dblink(:dblink_url, | ||
'SELECT * FROM w3w_commons.token_hourly_prices WHERE timestamp >= ''{start_date}'' ') | ||
AS t(symbol varchar, timestamp timestamp, price numeric); | ||
""" | ||
|
||
sql = token_price_sql_template.format(start_date=self.start_date) | ||
|
||
session = self.db_service.Session() | ||
|
||
start_time = time.time() | ||
|
||
session.execute(text(sql), {"start_date": self.start_date, "dblink_url": self.dblink_url}) | ||
|
||
session.commit() | ||
execution_time = time.time() - start_time | ||
print(f"----------- executed in {execution_time:.2f} seconds: init token price") | ||
|
||
session.close() | ||
|
||
def init_period_address_token_balance(self): | ||
session = self.db_service.Session() | ||
|
||
sql_template = """ | ||
delete from period_address_token_balances where period_date >= :start_date; | ||
""" | ||
start_time = time.time() | ||
session.execute(text(sql_template), {"start_date": self.start_date}) | ||
|
||
session.commit() | ||
execution_time = time.time() - start_time | ||
print(f"----------- executed in {execution_time:.2f} seconds: init period_address_token_balances") | ||
|
||
session.close() | ||
|
||
def run(self, **kwargs): | ||
self.start_date = kwargs["start_date"] | ||
self.end_date = kwargs["end_date"] | ||
|
||
# self.init_token_price() | ||
# self.init_period_address_token_balance() | ||
|
||
for function_name in self.job_list: | ||
func = getattr(self, function_name, None) | ||
if callable(func): | ||
func() | ||
else: | ||
print(f"Function {function_name} does not exist") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
class JobListGenerator(object): | ||
def __init__(self, job_name): | ||
self.job_name = job_name | ||
|
||
def get_initialization_jobs(self): | ||
job_list = [] | ||
if self.job_name == "FBTC": | ||
job_list = ["init_token_price", "init_period_address_token_balance"] | ||
return job_list | ||
|
||
def get_disordered_jobs(self): | ||
job_list = [] | ||
|
||
if self.job_name == "FBTC": | ||
job_list = [ | ||
"daily_feature_holding_balance_staked_fbtc_detail.sql", | ||
"daily_feature_holding_balance_uniswap_v3.sql", | ||
"daily_address_token_balances", | ||
"daily_feature_erc20_token_supply_records.sql", | ||
# 'daily_feature_erc1155_token_holdings.sql', | ||
# 'daily_feature_erc1155_token_supply_records.sql' | ||
] | ||
elif self.job_name == "EXPLORE": | ||
job_list = [ | ||
"daily_explore_aggregates.sql", | ||
] | ||
|
||
return job_list | ||
|
||
def get_order_jobs(self): | ||
job_list = [] | ||
|
||
if self.job_name == "FBTC": | ||
job_list = [ | ||
"period_address_token_balances", | ||
"period_feature_holding_balance_uniswap_v3.sql", | ||
"period_feature_staked_fbtc_detail_records.sql", | ||
"period_feature_holding_balance_staked_fbtc_detail.sql", | ||
# 'period_feature_erc1155_token_holdings.sql', | ||
"period_feature_erc1155_token_supply_records.sql", | ||
"period_feature_holding_balance_merchantmoe.sql", | ||
"period_feature_erc20_token_supply_records.sql", | ||
"period_feature_holding_balance_dodo.sql", | ||
"period_feature_holding_balance_lendle.sql", | ||
"period_feature_defi_wallet_fbtc_aggregates.py", | ||
] | ||
|
||
return job_list |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from flask_sqlalchemy import SQLAlchemy | ||
from sqlalchemy import DATE, TIMESTAMP, Column, Index, func | ||
from sqlalchemy.dialects.postgresql import BYTEA, NUMERIC, VARCHAR | ||
|
||
from common.models import HemeraModel, general_converter | ||
|
||
|
||
class PeriodFeatureHoldingBalanceLendle(HemeraModel): | ||
__tablename__ = "period_feature_holding_balance_lendle" | ||
|
||
period_date = Column(DATE, primary_key=True, nullable=False) | ||
wallet_address = Column(BYTEA, primary_key=True) | ||
protocol_id = Column(VARCHAR, primary_key=True) | ||
contract_address = Column(BYTEA, primary_key=True) | ||
|
||
token_symbol = Column(VARCHAR) | ||
token_address = Column(BYTEA) | ||
|
||
balance = Column(NUMERIC(100, 18)) | ||
|
||
create_time = Column(TIMESTAMP, server_default=func.now()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need chain name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because some configurations depend on the chain, just like the selection of protocol ID in Uniswap v3.
And some table fields have chain names.
But it is true that this will be removed due to the configuration change of the address