KusionStack / konfig

Shared repository of application models and components, and CI suite for GitOps workflows
Apache License 2.0
27 stars 32 forks source link

How to do `units.NumberMultiplier * float` operator? #30

Closed LeoLiuYan closed 1 year ago

LeoLiuYan commented 2 years ago

General Question

When users want to use 2048Mi memory, for example, and we set resources.memroy.limits = 2048Mi, but set resources.memroy.requests = 2048Mi * (a float ratio).

import units
import base.pkg.kusion_models.kube.frontend.resource

a: units.NumberMultiplier = 2048Mi
ratio: float = 0.01

res: resource.Resource = {
    cpu = 1 * ratio        # How to convert to "10m"?
    memory = a * ratio  # error: unsupport
    #memory = units.to_Mi(float(int(a)) * ratio) # error: to_Mi unsupport a float argument
}

@Peefy @chai2010

Peefy commented 2 years ago

@LeoLiuYan In KCL, numeric units exist as a special type, which does not allow arithmetic operations, because str(1024Mi) == "1024Mi" can be written directly, but when they are calculated and then use the str function, KCL compiler don't know what unit to take.

Therefore, If you really want to support resource assignment as a string type, you can directly extend the definition of Resource as follows:

import units

type Unit = units.NumberMultiplier

schema Resource:
    cpu?: int | Unit = 1
    memory?: str | Unit = 1024Mi
    disk?: str | Unit = 10Gi

Where, the type of memory is str | Unit

LeoLiuYan commented 2 years ago

@Peefy

OK. But this is a common operation when set the value of resources.limits and resources.requests, will the KCL to support an easy way to do this operation.

Peefy commented 2 years ago

OK. But this is a common operation when set the value of resources.limits and resources.requests, will the KCL to support a easy way to do this operation.

Got it. We'll consider an easier way to deal with resource.

Peefy commented 2 years ago

However, we can convert the numeric unit literal value into an integer through the int() function, and then call the functions in the units package or spliced into the corresponding unit string.

Peefy commented 2 years ago
import units
import math

a: units.NumberMultiplier = 2048Mi
ratio: float = 0.3
cpu: int | str = 1

res = {
    cpu = str(int(int(cpu) * ratio * 1000)) + "m"
    memory = units.to_Mi(int(int(a) * ratio))
}

@LeoLiuYan

Peefy commented 2 years ago

@LeoLiuYan In KCL, numeric units exist as a special type, which does not allow arithmetic operations, because str(1024Mi) == "1024Mi" can be written directly, but when they are calculated and then use the str function, KCL compiler don't know what unit to take.

Therefore, If you really want to support resource assignment as a string type, you can directly extend the definition of Resource as follows:

import units

type Unit = units.NumberMultiplier

schema Resource:
    cpu?: int | Unit = 1
    memory?: str | Unit = 1024Mi
    disk?: str | Unit = 10Gi

Where, the type of memory is str | Unit

In addition, it is not complete to only support the operation of numerical unit types and integers. For addition, 1Mi + 1Ki is ambiguous, and the calculation result unit is uncertain.