Skip to content

Commit cb0ebdf

Browse files
committed
Support for SQLite quota tables
1 parent 1cbaf7f commit cb0ebdf

File tree

1 file changed

+97
-34
lines changed

1 file changed

+97
-34
lines changed

src/runners/quota_scheduler.py

Lines changed: 97 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,38 @@
3333
"""
3434

3535

36-
INCREASE_QUOTA_STATEMENT = """
36+
INCREASE_QUOTA_STATEMENT_PG = """
3737
UPDATE quota_limits
3838
SET available=available+%s, revoked_at=NOW()
3939
WHERE subject=%s
4040
AND revoked_at < NOW() - INTERVAL %s ;
4141
"""
4242

43-
RESET_QUOTA_STATEMENT = """
43+
44+
INCREASE_QUOTA_STATEMENT_SQLITE = """
45+
UPDATE quota_limits
46+
SET available=available+?, revoked_at=datetime('now')
47+
WHERE subject=?
48+
AND revoked_at < datetime('now', ?);
49+
"""
50+
51+
52+
RESET_QUOTA_STATEMENT_PG = """
4453
UPDATE quota_limits
4554
SET available=%s, revoked_at=NOW()
4655
WHERE subject=%s
4756
AND revoked_at < NOW() - INTERVAL %s ;
4857
"""
4958

5059

60+
RESET_QUOTA_STATEMENT_SQLITE = """
61+
UPDATE quota_limits
62+
SET available=?, revoked_at=datetime('now')
63+
WHERE subject=?
64+
AND revoked_at < datetime('now', ?);
65+
"""
66+
67+
5168
def quota_scheduler(config: QuotaHandlersConfiguration) -> bool:
5269
"""Quota scheduler task."""
5370
if config is None:
@@ -70,6 +87,9 @@ def quota_scheduler(config: QuotaHandlersConfiguration) -> bool:
7087
init_tables(connection)
7188
period = config.scheduler.period
7289

90+
increase_quota_statement = get_increase_quota_statement(config)
91+
reset_quota_statement = get_reset_quota_statement(config)
92+
7393
logger.info(
7494
"Quota scheduler started in separated thread with period set to %d seconds",
7595
period,
@@ -79,8 +99,10 @@ def quota_scheduler(config: QuotaHandlersConfiguration) -> bool:
7999
logger.info("Quota scheduler sync started")
80100
for limiter in config.limiters:
81101
try:
82-
quota_revocation(connection, limiter)
83-
except Exception as e: # pylint: disable=broad-exception-caught)
102+
quota_revocation(
103+
connection, limiter, increase_quota_statement, reset_quota_statement
104+
)
105+
except Exception as e: # pylint: disable=broad-exception-caught
84106
logger.error("Quota revoke error: %s", e)
85107
logger.info("Quota scheduler sync finished")
86108
sleep(period)
@@ -89,7 +111,26 @@ def quota_scheduler(config: QuotaHandlersConfiguration) -> bool:
89111
return True
90112

91113

92-
def quota_revocation(connection: Any, quota_limiter: QuotaLimiterConfiguration) -> None:
114+
def get_increase_quota_statement(config: QuotaHandlersConfiguration) -> str:
115+
"""Get the SQL statement to increase quota."""
116+
if config.sqlite is not None:
117+
return INCREASE_QUOTA_STATEMENT_SQLITE
118+
return INCREASE_QUOTA_STATEMENT_PG
119+
120+
121+
def get_reset_quota_statement(config: QuotaHandlersConfiguration) -> str:
122+
"""Get the SQL statement to reset quota."""
123+
if config.sqlite is not None:
124+
return RESET_QUOTA_STATEMENT_SQLITE
125+
return RESET_QUOTA_STATEMENT_PG
126+
127+
128+
def quota_revocation(
129+
connection: Any,
130+
quota_limiter: QuotaLimiterConfiguration,
131+
increase_quota_statement: str,
132+
reset_quota_statement: str,
133+
) -> None:
93134
"""Quota revocation mechanism."""
94135
logger.info(
95136
"Quota revocation mechanism for limiter '%s' of type '%s'",
@@ -107,17 +148,29 @@ def quota_revocation(connection: Any, quota_limiter: QuotaLimiterConfiguration)
107148

108149
if quota_limiter.quota_increase is not None:
109150
increase_quota(
110-
connection, subject_id, quota_limiter.quota_increase, quota_limiter.period
151+
connection,
152+
increase_quota_statement,
153+
subject_id,
154+
quota_limiter.quota_increase,
155+
quota_limiter.period,
111156
)
112157

113158
if quota_limiter.initial_quota is not None and quota_limiter.initial_quota > 0:
114159
reset_quota(
115-
connection, subject_id, quota_limiter.initial_quota, quota_limiter.period
160+
connection,
161+
reset_quota_statement,
162+
subject_id,
163+
quota_limiter.initial_quota,
164+
quota_limiter.period,
116165
)
117166

118167

119168
def increase_quota(
120-
connection: Any, subject_id: str, increase_by: int, period: str
169+
connection: Any,
170+
update_statement: str,
171+
subject_id: str,
172+
increase_by: int,
173+
period: str,
121174
) -> None:
122175
"""Increase quota by specified amount."""
123176
logger.info(
@@ -127,41 +180,51 @@ def increase_quota(
127180
period,
128181
)
129182

130-
update_statement = INCREASE_QUOTA_STATEMENT
131-
132-
with connection.cursor() as cursor:
133-
cursor.execute(
134-
update_statement,
135-
(
136-
increase_by,
137-
subject_id,
138-
period,
139-
),
140-
)
141-
logger.info("Changed %d rows in database", cursor.rowcount)
183+
# for compatibility with SQLite it is not possible to use context manager
184+
# there
185+
cursor = connection.cursor()
186+
cursor.execute(
187+
update_statement,
188+
(
189+
increase_by,
190+
subject_id,
191+
period,
192+
),
193+
)
194+
cursor.close()
195+
connection.commit()
196+
logger.info("Changed %d rows in database", cursor.rowcount)
142197

143198

144-
def reset_quota(connection: Any, subject_id: str, reset_to: int, period: str) -> None:
199+
def reset_quota(
200+
connection: Any,
201+
update_statement: str,
202+
subject_id: str,
203+
reset_to: int,
204+
period: str,
205+
) -> None:
145206
"""Reset quota to specified amount."""
146207
logger.info(
147-
"Reseting quota for subject '%s' to %d when period %s is reached",
208+
"Resetting quota for subject '%s' to %d when period %s is reached",
148209
subject_id,
149210
reset_to,
150211
period,
151212
)
152213

153-
update_statement = RESET_QUOTA_STATEMENT
154-
155-
with connection.cursor() as cursor:
156-
cursor.execute(
157-
update_statement,
158-
(
159-
reset_to,
160-
subject_id,
161-
period,
162-
),
163-
)
164-
logger.info("Changed %d rows in database", cursor.rowcount)
214+
# for compatibility with SQLite it is not possible to use context manager
215+
# there
216+
cursor = connection.cursor()
217+
cursor.execute(
218+
update_statement,
219+
(
220+
reset_to,
221+
subject_id,
222+
period,
223+
),
224+
)
225+
cursor.close()
226+
connection.commit()
227+
logger.info("Changed %d rows in database", cursor.rowcount)
165228

166229

167230
def get_subject_id(limiter_type: str) -> str:

0 commit comments

Comments
 (0)