Skip to content

Commit

Permalink
feat: Add GraphQL field rolling_count to check current rate limit w…
Browse files Browse the repository at this point in the history
…ithout increasing (#2050)

Co-authored-by: Joongi Kim <[email protected]>
  • Loading branch information
rapsealk and achimnol authored Jul 13, 2024
1 parent 1bbd178 commit 5981834
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 1 deletion.
1 change: 1 addition & 0 deletions changes/2050.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Introduce the `rolling_count` GraphQL field to provide the current rate limit counter for a keypair within the designated time window slice
1 change: 0 additions & 1 deletion src/ai/backend/client/cli/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import click

# from ai.backend.client.output.fields import image_fields
from ai.backend.cli.main import main
from ai.backend.cli.types import ExitCode
from ai.backend.client.exceptions import BackendAPIError
Expand Down
3 changes: 3 additions & 0 deletions src/ai/backend/manager/api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ type KeyPair implements Item {
last_used: DateTime
rate_limit: Int
num_queries: Int

"""Added in 24.09.0."""
rolling_count: Int
user: UUID
projects: [String]
ssh_public_key: String
Expand Down
15 changes: 15 additions & 0 deletions src/ai/backend/manager/models/keypair.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
from cryptography.hazmat.primitives.asymmetric import rsa
from dateutil.parser import parse as dtparse
from graphene.types.datetime import DateTime as GQLDateTime
from redis.asyncio import Redis
from sqlalchemy.engine.row import Row
from sqlalchemy.ext.asyncio import AsyncConnection as SAConnection
from sqlalchemy.orm import relationship
from sqlalchemy.sql.expression import false

from ai.backend.common import msgpack, redis_helper
from ai.backend.common.defs import REDIS_RLIM_DB
from ai.backend.common.types import AccessKey, SecretKey

if TYPE_CHECKING:
Expand Down Expand Up @@ -167,6 +169,7 @@ class Meta:
last_used = GQLDateTime()
rate_limit = graphene.Int()
num_queries = graphene.Int()
rolling_count = graphene.Int(description="Added in 24.09.0.")
user = graphene.UUID()
projects = graphene.List(lambda: graphene.String)

Expand Down Expand Up @@ -228,6 +231,18 @@ async def resolve_num_queries(self, info: graphene.ResolveInfo) -> int:
return n
return 0

async def resolve_rolling_count(self, info: graphene.ResolveInfo) -> int:
ctx: GraphQueryContext = info.context
redis_rlim = redis_helper.get_redis_object(
ctx.shared_config.data["redis"], name="ratelimit", db=REDIS_RLIM_DB
)

async def _zcard(r: Redis):
return await r.zcard(self.access_key)

ret = await redis_helper.execute(redis_rlim, _zcard)
return int(ret) if ret is not None else 0

async def resolve_vfolders(self, info: graphene.ResolveInfo) -> Sequence[VirtualFolder]:
ctx: GraphQueryContext = info.context
loader = ctx.dataloader_manager.get_loader(ctx, "VirtualFolder")
Expand Down

0 comments on commit 5981834

Please sign in to comment.