Skip to content
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

Introduce neuro config quota show #1156

Merged
merged 10 commits into from
Nov 8, 2019
Merged

Introduce neuro config quota show #1156

merged 10 commits into from
Nov 8, 2019

Conversation

atemate
Copy link
Contributor

@atemate atemate commented Nov 8, 2019

Closes #1141

@atemate
Copy link
Contributor Author

atemate commented Nov 8, 2019

GET /stats/users/{name} is currently deployed only on dev: default cluster only

Copy link
Contributor

@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new public API requires documentation


@dataclass(frozen=True)
class QuotaDetails:
spent_minutes: int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use minutes in API but float seconds.
float("inf") is for infinity, please use this constant instead of None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use minutes in API but float seconds.

for this, we will need to change the server-side API. Note, currently, we get the time in minutes (see neuro-inc/platform-api#901).

Should we change the API?

Copy link
Contributor

@asvetlov asvetlov Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary, you can multiply by 60 on the client.
In python there are two time representations: float and datetime.
It is confusing enough right now, adding yet another notation makes everything even worse and less usable: people will always convert minutes into something more convenient.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need QuotaDetails? Why not use just float or Optional[timedelta]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary, you can multiply by 60 on the client.

OK, I will change ..._minutes: int to ..._seconds: float everywhere. But for me personally it'd be confusing if I see GPU spent: 00h 01m 00s, then I run a job for 30 seconds and I still see: GPU spent: 00h 01m 00s. I think, if we need to show time in seconds, the API protocol should be changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need QuotaDetails? Why not use just float or Optional[timedelta]?

In the first version of my code, there were just fields gpu_spent_minutes, cpu_limit_minutes, etc. But since the lines for CPU and GPU should use the same formatting method _format_quota_details, I found it useful to introduce an additional abstraction QuotaDetails. Though, if it's an eyesore for you, I'm OK to get rid of it. Should I? cc @serhiy-storchaka

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API uses seconds (omit the suffix from field names please).
CLI can stay with minutes, it makes sense.

Like we return file size as bytes in the storage API but show it as gigabytes for large files in CLI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flat structure with short field names is better IMHO

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API uses seconds (omit the suffix from field names please). CLI can stay with minutes, it makes sense.

Fixed.

Why do we need QuotaDetails? Why not use just float or Optional[timedelta]?

fixed to use a flat structure.

self._core = core
self._config = config

async def get(self) -> QuotaInfo:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to get quota for another user?
I can do it if have appropriate permissions, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need a funcitonality to see other user's quota? cc @mariyadavydova

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We obviously support it by REST API. Otherwise please modify the server as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, yes, we need a functionality to see other user's quota (for example, I would like to be able to see the quotas left for our free tier users). However, config seems to be a bad place for such functionality, as other config commands refer to your personal information (or your server's). Let's file another issue and think where we should put the quota-related functionality (this refers to other discussions in this PR too). This particular issue should solve the immediate problem - "How do I, free tier user, get to know how much quota I have?".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We obviously support it by REST API. Otherwise please modify the server as well.

Please, don't :) I use this functionality to bump quotas via REST API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mariyadavydova here is a public API class, not neuro config CLI command group.
API is more generic (and potentially harder to change publishing).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I'm sorry. Then I think that we should update this class accordingly and keep it as is for a while, as this quota functionality is emerging now and we do not have a clear understanding of how it should be organized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async def get(self, user: Optional[str]=None), the default None is for self.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already done

@@ -28,6 +29,11 @@ def config() -> None:
"""Client configuration."""


@group()
def quota() -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use nested group, neuro config show-quota is just fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, the team decided to use neuro config quota show in order to extend quota group with additional funcitonality: neuro config quota add, etc. Perhaps, the good solution would be to make the group quota non-nested: neuro quota show

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to put quota management into the config group, that's it.
Please don't add redundant nesting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the common user cannot change quota.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please keep in mind: later, after organizations implementing, we may find that quota better fits somewhere in the organization management structures. Now we don't add top-level neuro quota but put a simple command into the config group for this reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@atemate
Copy link
Contributor Author

atemate commented Nov 8, 2019

All comments considered, everyone thanks for your review!

@atemate atemate requested a review from asvetlov November 8, 2019 12:55
@atemate
Copy link
Contributor Author

atemate commented Nov 8, 2019

Currently adding the documentation on API

@lgtm-com
Copy link

lgtm-com bot commented Nov 8, 2019

This pull request fixes 5 alerts when merging cbee0c6 into 29585e5 - view on LGTM.com

fixed alerts:

  • 3 for Conflicting attributes in base classes
  • 2 for Module is imported with 'import' and 'import from'

gpu_time_limit: float

@property
def cpu_time_remaining(self) -> float:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the property is equal to max(self.cpi_time_spent - self.cpu_time_limit).
Do we need a property at all?

@atemate
Copy link
Contributor Author

atemate commented Nov 8, 2019

  1. Added changelog message
  2. Hide API for quota in order to not expose API that will likely change soon. Now, dataclass _QuotaInfo is protected, and class Client has a temporary protected method _get_quota_info()

@atemate atemate requested a review from asvetlov November 8, 2019 14:21
@@ -103,3 +106,27 @@ def _get_session_cookie(self) -> Optional["Morsel[str]"]:
if cookie.key == "NEURO_SESSION":
return cookie
return None

async def _get_quota_info(self, user: Optional[str] = None) -> _QuotaInfo:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep client._quota private API.
There is no need to mess client.py with quota-specific things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@lgtm-com
Copy link

lgtm-com bot commented Nov 8, 2019

This pull request introduces 7 alerts when merging 0634ed8 into 29585e5 - view on LGTM.com

new alerts:

  • 4 for Module is imported with 'import' and 'import from'
  • 3 for Conflicting attributes in base classes

@lgtm-com
Copy link

lgtm-com bot commented Nov 8, 2019

This pull request introduces 2 alerts when merging 3f05ebb into 29585e5 - view on LGTM.com

new alerts:

  • 2 for Module is imported with 'import' and 'import from'

@atemate atemate merged commit d869cb9 into master Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce neuro config quota show
5 participants