Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cli/cluster/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

func Delete(operatorConfig OperatorConfig, apiName string, keepCache bool, force bool) (schema.DeleteResponse, error) {
if !force {
readyReplicas := getReadySyncAPIReplicasOrNil(operatorConfig, apiName)
readyReplicas := getReadyRealtimeAPIReplicasOrNil(operatorConfig, apiName)
if readyReplicas != nil && *readyReplicas > 2 {
prompt.YesOrExit(fmt.Sprintf("are you sure you want to delete %s (which has %d live replicas)?", apiName, *readyReplicas), "", "")
}
Expand All @@ -54,7 +54,7 @@ func Delete(operatorConfig OperatorConfig, apiName string, keepCache bool, force
return deleteRes, nil
}

func getReadySyncAPIReplicasOrNil(operatorConfig OperatorConfig, apiName string) *int32 {
func getReadyRealtimeAPIReplicasOrNil(operatorConfig OperatorConfig, apiName string) *int32 {
httpRes, err := HTTPGet(operatorConfig, "/get/"+apiName)
if err != nil {
return nil
Expand All @@ -65,11 +65,11 @@ func getReadySyncAPIReplicasOrNil(operatorConfig OperatorConfig, apiName string)
return nil
}

if apiRes.SyncAPI == nil {
if apiRes.RealtimeAPI == nil {
return nil
}

totalReady := apiRes.SyncAPI.Status.Updated.Ready + apiRes.SyncAPI.Status.Stale.Ready
totalReady := apiRes.RealtimeAPI.Status.Updated.Ready + apiRes.RealtimeAPI.Status.Stale.Ready
return &totalReady
}

Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func getAPICommandsMessage(results []schema.DeployResult, envName string) string
items.Add(fmt.Sprintf("cortex get %s%s", apiName, envArg), "(show api info)")

for _, result := range results {
if result.API.Kind == userconfig.SyncAPIKind {
if result.API.Kind == userconfig.RealtimeAPIKind {
items.Add(fmt.Sprintf("cortex logs %s%s", apiName, envArg), "(stream api logs)")
break
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,6 @@ func ErrorDeployFromTopLevelDir(genericDirName string, providerType types.Provid
}
return errors.WithStack(&errors.Error{
Kind: ErrDeployFromTopLevelDir,
Message: fmt.Sprintf("cannot deploy from your %s directory - when deploying your API, cortex sends all files in your project directory (i.e. the directory which contains cortex.yaml) to your %s (see https://docs.cortex.dev/v/%s/deployments/syncapi/predictors#project-files for Sync API and https://docs.cortex.dev/v/%s/deployments/batchapi/predictors#project-files for Batch API); therefore it is recommended to create a subdirectory for your project files", genericDirName, targetStr, consts.CortexVersionMinor, consts.CortexVersionMinor),
Message: fmt.Sprintf("cannot deploy from your %s directory - when deploying your API, cortex sends all files in your project directory (i.e. the directory which contains cortex.yaml) to your %s (see https://docs.cortex.dev/v/%s/deployments/realtime-api/predictors#project-files for Realtime API and https://docs.cortex.dev/v/%s/deployments/batch-api/predictors#project-files for Batch API); therefore it is recommended to create a subdirectory for your project files", genericDirName, targetStr, consts.CortexVersionMinor, consts.CortexVersionMinor),
})
}
62 changes: 31 additions & 31 deletions cli/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (

const (
_titleEnvironment = "env"
_titleSyncAPI = "sync api"
_titleRealtimeAPI = "realtime api"
_titleStatus = "status"
_titleUpToDate = "up-to-date"
_titleStale = "stale"
Expand Down Expand Up @@ -150,12 +150,12 @@ func getAPIsInAllEnvironments() (string, error) {
return "", err
}

var allSyncAPIs []schema.SyncAPI
var allSyncAPIEnvs []string
var allRealtimeAPIs []schema.RealtimeAPI
var allRealtimeAPIEnvs []string
var allBatchAPIs []schema.BatchAPI
var allBatchAPIEnvs []string
var allAPISplitters []schema.APISplitter
var allAPISplitterEnvs []string
var allTrafficSplitters []schema.TrafficSplitter
var allTrafficSplitterEnvs []string

errorsMap := map[string]error{}
// get apis from both environments
Expand All @@ -172,23 +172,23 @@ func getAPIsInAllEnvironments() (string, error) {
for range apisRes.BatchAPIs {
allBatchAPIEnvs = append(allBatchAPIEnvs, env.Name)
}
for range apisRes.SyncAPIs {
allSyncAPIEnvs = append(allSyncAPIEnvs, env.Name)
for range apisRes.RealtimeAPIs {
allRealtimeAPIEnvs = append(allRealtimeAPIEnvs, env.Name)
}
for range apisRes.APISplitters {
allAPISplitterEnvs = append(allAPISplitterEnvs, env.Name)
for range apisRes.TrafficSplitters {
allTrafficSplitterEnvs = append(allTrafficSplitterEnvs, env.Name)
}
allSyncAPIs = append(allSyncAPIs, apisRes.SyncAPIs...)
allRealtimeAPIs = append(allRealtimeAPIs, apisRes.RealtimeAPIs...)
allBatchAPIs = append(allBatchAPIs, apisRes.BatchAPIs...)
allAPISplitters = append(allAPISplitters, apisRes.APISplitters...)
allTrafficSplitters = append(allTrafficSplitters, apisRes.TrafficSplitters...)
} else {
errorsMap[env.Name] = err
}
}

out := ""

if len(allSyncAPIs) == 0 && len(allBatchAPIs) == 0 && len(allAPISplitters) == 0 {
if len(allRealtimeAPIs) == 0 && len(allBatchAPIs) == 0 && len(allTrafficSplitters) == 0 {
if len(errorsMap) == 1 {
// Print the error if there is just one
exit.Error(errors.FirstErrorInMap(errorsMap))
Expand All @@ -203,9 +203,9 @@ func getAPIsInAllEnvironments() (string, error) {
out += t.MustFormat()
}

if len(allSyncAPIs) > 0 {
t := syncAPIsTable(allSyncAPIs, allSyncAPIEnvs)
if strset.New(allSyncAPIEnvs...).IsEqual(strset.New(types.LocalProviderType.String())) {
if len(allRealtimeAPIs) > 0 {
t := realtimeAPIsTable(allRealtimeAPIs, allRealtimeAPIEnvs)
if strset.New(allRealtimeAPIEnvs...).IsEqual(strset.New(types.LocalProviderType.String())) {
hideReplicaCountColumns(&t)
}

Expand All @@ -216,10 +216,10 @@ func getAPIsInAllEnvironments() (string, error) {
out += t.MustFormat()
}

if len(allAPISplitters) > 0 {
t := apiSplitterListTable(allAPISplitters, allAPISplitterEnvs)
if len(allTrafficSplitters) > 0 {
t := trafficSplitterListTable(allTrafficSplitters, allTrafficSplitterEnvs)

if len(allSyncAPIs) > 0 || len(allBatchAPIs) > 0 {
if len(allRealtimeAPIs) > 0 || len(allBatchAPIs) > 0 {
out += "\n"
}

Expand Down Expand Up @@ -267,7 +267,7 @@ func getAPIsByEnv(env cliconfig.Environment, printEnv bool) (string, error) {
}
}

if len(apisRes.SyncAPIs) == 0 && len(apisRes.BatchAPIs) == 0 && len(apisRes.APISplitters) == 0 {
if len(apisRes.RealtimeAPIs) == 0 && len(apisRes.BatchAPIs) == 0 && len(apisRes.TrafficSplitters) == 0 {
return console.Bold("no apis are deployed"), nil
}

Expand All @@ -285,13 +285,13 @@ func getAPIsByEnv(env cliconfig.Environment, printEnv bool) (string, error) {
out += t.MustFormat()
}

if len(apisRes.SyncAPIs) > 0 {
if len(apisRes.RealtimeAPIs) > 0 {
envNames := []string{}
for range apisRes.SyncAPIs {
for range apisRes.RealtimeAPIs {
envNames = append(envNames, env.Name)
}

t := syncAPIsTable(apisRes.SyncAPIs, envNames)
t := realtimeAPIsTable(apisRes.RealtimeAPIs, envNames)
t.FindHeaderByTitle(_titleEnvironment).Hidden = true

if len(apisRes.BatchAPIs) > 0 {
Expand All @@ -305,16 +305,16 @@ func getAPIsByEnv(env cliconfig.Environment, printEnv bool) (string, error) {
out += t.MustFormat()
}

if len(apisRes.APISplitters) > 0 {
if len(apisRes.TrafficSplitters) > 0 {
envNames := []string{}
for range apisRes.APISplitters {
for range apisRes.TrafficSplitters {
envNames = append(envNames, env.Name)
}

t := apiSplitterListTable(apisRes.APISplitters, envNames)
t := trafficSplitterListTable(apisRes.TrafficSplitters, envNames)
t.FindHeaderByTitle(_titleEnvironment).Hidden = true

if len(apisRes.BatchAPIs) > 0 || len(apisRes.SyncAPIs) > 0 {
if len(apisRes.BatchAPIs) > 0 || len(apisRes.RealtimeAPIs) > 0 {
out += "\n"
}

Expand Down Expand Up @@ -357,11 +357,11 @@ func getAPI(env cliconfig.Environment, apiName string) (string, error) {
return "", err
}

if apiRes.SyncAPI != nil {
return syncAPITable(apiRes.SyncAPI, env)
if apiRes.RealtimeAPI != nil {
return realtimeAPITable(apiRes.RealtimeAPI, env)
}
if apiRes.APISplitter != nil {
return apiSplitterTable(apiRes.APISplitter, env)
if apiRes.TrafficSplitter != nil {
return trafficSplitterTable(apiRes.TrafficSplitter, env)
}
return batchAPITable(*apiRes.BatchAPI), nil
}
Expand All @@ -375,7 +375,7 @@ func getAPI(env cliconfig.Environment, apiName string) (string, error) {
return "", err
}

return syncAPITable(apiRes.SyncAPI, env)
return realtimeAPITable(apiRes.RealtimeAPI, env)
}

func titleStr(title string) string {
Expand Down
68 changes: 34 additions & 34 deletions cli/cmd/lib_sync_apis.go → cli/cmd/lib_realtime_apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,82 +41,82 @@ import (
"github.com/cortexlabs/cortex/pkg/types/userconfig"
)

func syncAPITable(syncAPI *schema.SyncAPI, env cliconfig.Environment) (string, error) {
func realtimeAPITable(realtimeAPI *schema.RealtimeAPI, env cliconfig.Environment) (string, error) {
var out string

t := syncAPIsTable([]schema.SyncAPI{*syncAPI}, []string{env.Name})
t := realtimeAPIsTable([]schema.RealtimeAPI{*realtimeAPI}, []string{env.Name})
t.FindHeaderByTitle(_titleEnvironment).Hidden = true
t.FindHeaderByTitle(_titleSyncAPI).Hidden = true
t.FindHeaderByTitle(_titleRealtimeAPI).Hidden = true
if env.Provider == types.LocalProviderType {
hideReplicaCountColumns(&t)
}

out += t.MustFormat()

if env.Provider != types.LocalProviderType && syncAPI.Spec.Monitoring != nil {
switch syncAPI.Spec.Monitoring.ModelType {
if env.Provider != types.LocalProviderType && realtimeAPI.Spec.Monitoring != nil {
switch realtimeAPI.Spec.Monitoring.ModelType {
case userconfig.ClassificationModelType:
out += "\n" + classificationMetricsStr(&syncAPI.Metrics)
out += "\n" + classificationMetricsStr(&realtimeAPI.Metrics)
case userconfig.RegressionModelType:
out += "\n" + regressionMetricsStr(&syncAPI.Metrics)
out += "\n" + regressionMetricsStr(&realtimeAPI.Metrics)
}
}

if syncAPI.DashboardURL != "" {
out += "\n" + console.Bold("metrics dashboard: ") + syncAPI.DashboardURL + "\n"
if realtimeAPI.DashboardURL != "" {
out += "\n" + console.Bold("metrics dashboard: ") + realtimeAPI.DashboardURL + "\n"
}

out += "\n" + console.Bold("endpoint: ") + syncAPI.Endpoint
out += "\n" + console.Bold("endpoint: ") + realtimeAPI.Endpoint

out += fmt.Sprintf("\n%s curl %s -X POST -H \"Content-Type: application/json\" -d @sample.json\n", console.Bold("curl:"), syncAPI.Endpoint)
out += fmt.Sprintf("\n%s curl %s -X POST -H \"Content-Type: application/json\" -d @sample.json\n", console.Bold("curl:"), realtimeAPI.Endpoint)

if syncAPI.Spec.Predictor.Type == userconfig.TensorFlowPredictorType || syncAPI.Spec.Predictor.Type == userconfig.ONNXPredictorType {
out += "\n" + describeModelInput(&syncAPI.Status, syncAPI.Endpoint)
if realtimeAPI.Spec.Predictor.Type == userconfig.TensorFlowPredictorType || realtimeAPI.Spec.Predictor.Type == userconfig.ONNXPredictorType {
out += "\n" + describeModelInput(&realtimeAPI.Status, realtimeAPI.Endpoint)
}

out += titleStr("configuration") + strings.TrimSpace(syncAPI.Spec.UserStr(env.Provider))
out += titleStr("configuration") + strings.TrimSpace(realtimeAPI.Spec.UserStr(env.Provider))

return out, nil
}

func syncAPIsTable(syncAPIs []schema.SyncAPI, envNames []string) table.Table {
rows := make([][]interface{}, 0, len(syncAPIs))
func realtimeAPIsTable(realtimeAPIs []schema.RealtimeAPI, envNames []string) table.Table {
rows := make([][]interface{}, 0, len(realtimeAPIs))

var totalFailed int32
var totalStale int32
var total4XX int
var total5XX int

for i, syncAPI := range syncAPIs {
lastUpdated := time.Unix(syncAPI.Spec.LastUpdated, 0)
for i, realtimeAPI := range realtimeAPIs {
lastUpdated := time.Unix(realtimeAPI.Spec.LastUpdated, 0)
rows = append(rows, []interface{}{
envNames[i],
syncAPI.Spec.Name,
syncAPI.Status.Message(),
syncAPI.Status.Updated.Ready,
syncAPI.Status.Stale.Ready,
syncAPI.Status.Requested,
syncAPI.Status.Updated.TotalFailed(),
realtimeAPI.Spec.Name,
realtimeAPI.Status.Message(),
realtimeAPI.Status.Updated.Ready,
realtimeAPI.Status.Stale.Ready,
realtimeAPI.Status.Requested,
realtimeAPI.Status.Updated.TotalFailed(),
libtime.SinceStr(&lastUpdated),
latencyStr(&syncAPI.Metrics),
code2XXStr(&syncAPI.Metrics),
code4XXStr(&syncAPI.Metrics),
code5XXStr(&syncAPI.Metrics),
latencyStr(&realtimeAPI.Metrics),
code2XXStr(&realtimeAPI.Metrics),
code4XXStr(&realtimeAPI.Metrics),
code5XXStr(&realtimeAPI.Metrics),
})

totalFailed += syncAPI.Status.Updated.TotalFailed()
totalStale += syncAPI.Status.Stale.Ready
totalFailed += realtimeAPI.Status.Updated.TotalFailed()
totalStale += realtimeAPI.Status.Stale.Ready

if syncAPI.Metrics.NetworkStats != nil {
total4XX += syncAPI.Metrics.NetworkStats.Code4XX
total5XX += syncAPI.Metrics.NetworkStats.Code5XX
if realtimeAPI.Metrics.NetworkStats != nil {
total4XX += realtimeAPI.Metrics.NetworkStats.Code4XX
total5XX += realtimeAPI.Metrics.NetworkStats.Code5XX
}
}

return table.Table{
Headers: []table.Header{
{Title: _titleEnvironment},
{Title: _titleSyncAPI},
{Title: _titleRealtimeAPI},
{Title: _titleStatus},
{Title: _titleUpToDate},
{Title: _titleStale, Hidden: totalStale == 0},
Expand Down
Loading