@@ -20,6 +20,7 @@ package model
2020import (
2121 "github.com/duke-git/lancet/v2/strutil"
2222
23+ meshproto "github.com/apache/dubbo-admin/api/mesh/v1alpha1"
2324 "github.com/apache/dubbo-admin/pkg/config/app"
2425 meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1"
2526 coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model"
@@ -54,17 +55,18 @@ func NewSearchPaginationResult() *SearchPaginationResult {
5455}
5556
5657type SearchInstanceResp struct {
57- Ip string `json:"ip"`
58- Name string `json:"name"`
59- WorkloadName string `json:"workloadName"`
60- AppName string `json:"appName"`
61- DeployState string `json:"deployState"`
62- DeployCluster string `json:"deployCluster"`
63- RegisterState string `json:"registerState"`
64- RegisterClusters []string `json:"registerClusters"`
65- CreateTime string `json:"createTime"`
66- RegisterTime string `json:"registerTime"`
67- Labels map [string ]string `json:"labels"`
58+ Ip string `json:"ip"`
59+ Name string `json:"name"`
60+ WorkloadName string `json:"workloadName"`
61+ AppName string `json:"appName"`
62+ LifecycleState InstanceLifecycleState `json:"lifecycleState"`
63+ DeployState InstanceDeployState `json:"deployState"`
64+ DeployCluster string `json:"deployCluster"`
65+ RegisterState InstanceRegisterState `json:"registerState"`
66+ RegisterClusters []string `json:"registerClusters"`
67+ CreateTime string `json:"createTime"`
68+ RegisterTime string `json:"registerTime"`
69+ Labels map [string ]string `json:"labels"`
6870}
6971
7072func NewSearchInstanceResp () * SearchInstanceResp {
@@ -85,13 +87,10 @@ func (r *SearchInstanceResp) FromInstanceResource(instanceResource *meshresource
8587 if cfg .Engine != nil && cfg .Engine .ID == instance .SourceEngine {
8688 r .DeployCluster = cfg .Engine .Name
8789 }
88- if r .RegisterTime != "" {
89- r .RegisterState = "Registered"
90- } else {
91- r .RegisterState = "UnRegistered"
92- }
90+ r .RegisterState = DeriveInstanceRegisterState (instance )
9391 r .Labels = instance .Tags
94- r .DeployState = instance .DeployState
92+ r .DeployState = DeriveInstanceDeployState (instance )
93+ r .LifecycleState = DeriveInstanceLifecycleState (instance , r .DeployState , r .RegisterState )
9594 r .WorkloadName = instance .WorkloadName
9695 r .AppName = instance .AppName
9796 return r
@@ -104,23 +103,74 @@ type State struct {
104103 Value string `json:"value"`
105104}
106105
106+ // InstanceDeployState describes the runtime deployment state reported by the platform.
107+ type InstanceDeployState string
108+
109+ const (
110+ // InstanceDeployStateUnknown indicates the deployment state cannot be derived from runtime metadata.
111+ InstanceDeployStateUnknown InstanceDeployState = "Unknown"
112+ // InstanceDeployStatePending indicates the workload has been accepted but is not running yet.
113+ InstanceDeployStatePending InstanceDeployState = "Pending"
114+ // InstanceDeployStateStarting indicates the workload is running but not ready to serve.
115+ InstanceDeployStateStarting InstanceDeployState = "Starting"
116+ // InstanceDeployStateRunning indicates the workload is running and ready.
117+ InstanceDeployStateRunning InstanceDeployState = "Running"
118+ // InstanceDeployStateTerminating indicates the workload is shutting down.
119+ InstanceDeployStateTerminating InstanceDeployState = "Terminating"
120+ // InstanceDeployStateFailed indicates the workload has failed.
121+ InstanceDeployStateFailed InstanceDeployState = "Failed"
122+ // InstanceDeployStateSucceeded indicates the workload has completed successfully and exited.
123+ InstanceDeployStateSucceeded InstanceDeployState = "Succeeded"
124+ // InstanceDeployStateCrashing indicates the workload is repeatedly crashing or restarting.
125+ InstanceDeployStateCrashing InstanceDeployState = "Crashing"
126+ )
127+
128+ // InstanceRegisterState describes whether the instance is visible to the registry.
129+ type InstanceRegisterState string
130+
131+ const (
132+ // InstanceRegisterStateRegistered indicates the instance has been registered to the registry.
133+ InstanceRegisterStateRegistered InstanceRegisterState = "Registered"
134+ // InstanceRegisterStateUnregistered indicates the instance has not registered yet or has been removed.
135+ InstanceRegisterStateUnregistered InstanceRegisterState = "UnRegistered"
136+ )
137+
138+ // InstanceLifecycleState describes the user-facing lifecycle synthesized from deploy/register signals.
139+ type InstanceLifecycleState string
140+
141+ const (
142+ // InstanceLifecycleStateStarting indicates the instance is still warming up.
143+ InstanceLifecycleStateStarting InstanceLifecycleState = "Starting"
144+ // InstanceLifecycleStateServing indicates the instance is both running and registered.
145+ InstanceLifecycleStateServing InstanceLifecycleState = "Serving"
146+ // InstanceLifecycleStateDraining indicates the instance is running but has started unregistering.
147+ InstanceLifecycleStateDraining InstanceLifecycleState = "Draining"
148+ // InstanceLifecycleStateTerminating indicates the instance is shutting down.
149+ InstanceLifecycleStateTerminating InstanceLifecycleState = "Terminating"
150+ // InstanceLifecycleStateError indicates the instance is in an unexpected or failed state.
151+ InstanceLifecycleStateError InstanceLifecycleState = "Error"
152+ // InstanceLifecycleStateUnknown indicates the lifecycle cannot be inferred from current signals.
153+ InstanceLifecycleStateUnknown InstanceLifecycleState = "Unknown"
154+ )
155+
107156type InstanceDetailResp struct {
108- RpcPort int64 `json:"rpcPort"`
109- Ip string `json:"ip"`
110- AppName string `json:"appName"`
111- WorkloadName string `json:"workloadName"`
112- Labels map [string ]string `json:"labels"`
113- CreateTime string `json:"createTime"`
114- ReadyTime string `json:"readyTime"`
115- RegisterTime string `json:"registerTime"`
116- RegisterClusters []string `json:"registerClusters"`
117- DeployCluster string `json:"deployCluster"`
118- DeployState string `json:"deployState"`
119- RegisterState string `json:"registerState"`
120- Node string `json:"node"`
121- Image string `json:"image"`
122- Probes ProbeStruct `json:"probes"`
123- Tags map [string ]string `json:"tags"`
157+ RpcPort int64 `json:"rpcPort"`
158+ Ip string `json:"ip"`
159+ AppName string `json:"appName"`
160+ WorkloadName string `json:"workloadName"`
161+ Labels map [string ]string `json:"labels"`
162+ CreateTime string `json:"createTime"`
163+ ReadyTime string `json:"readyTime"`
164+ RegisterTime string `json:"registerTime"`
165+ RegisterClusters []string `json:"registerClusters"`
166+ DeployCluster string `json:"deployCluster"`
167+ LifecycleState InstanceLifecycleState `json:"lifecycleState"`
168+ DeployState InstanceDeployState `json:"deployState"`
169+ RegisterState InstanceRegisterState `json:"registerState"`
170+ Node string `json:"node"`
171+ Image string `json:"image"`
172+ Probes ProbeStruct `json:"probes"`
173+ Tags map [string ]string `json:"tags"`
124174}
125175
126176const (
@@ -158,16 +208,9 @@ func FromInstanceResource(res *meshresource.InstanceResource, cfg app.AdminConfi
158208 if cfg .Engine .ID == res .Spec .SourceEngine {
159209 r .DeployCluster = cfg .Engine .Name
160210 }
161- if strutil .IsNotBlank (instance .DeployState ) {
162- r .DeployState = instance .DeployState
163- } else {
164- r .DeployState = "Unknown"
165- }
166- if strutil .IsBlank (r .RegisterTime ) {
167- r .RegisterState = "UnRegistered"
168- } else {
169- r .RegisterState = "Registered"
170- }
211+ r .DeployState = DeriveInstanceDeployState (instance )
212+ r .RegisterState = DeriveInstanceRegisterState (instance )
213+ r .LifecycleState = DeriveInstanceLifecycleState (instance , r .DeployState , r .RegisterState )
171214 r .Node = instance .Node
172215 r .Image = instance .Image
173216 r .Probes = ProbeStruct {}
@@ -196,3 +239,69 @@ func FromInstanceResource(res *meshresource.InstanceResource, cfg app.AdminConfi
196239 }
197240 return r
198241}
242+
243+ func DeriveInstanceDeployState (instance * meshproto.Instance ) InstanceDeployState {
244+ if instance == nil || strutil .IsBlank (instance .DeployState ) {
245+ return InstanceDeployStateUnknown
246+ }
247+ deployState := InstanceDeployState (instance .DeployState )
248+ switch deployState {
249+ case InstanceDeployStateRunning :
250+ if ! isPodReady (instance ) {
251+ return InstanceDeployStateStarting
252+ }
253+ return InstanceDeployStateRunning
254+ default :
255+ return deployState
256+ }
257+ }
258+
259+ func DeriveInstanceRegisterState (instance * meshproto.Instance ) InstanceRegisterState {
260+ if instance == nil || strutil .IsBlank (instance .RegisterTime ) {
261+ return InstanceRegisterStateUnregistered
262+ }
263+ return InstanceRegisterStateRegistered
264+ }
265+
266+ func DeriveInstanceLifecycleState (
267+ instance * meshproto.Instance ,
268+ deployState InstanceDeployState ,
269+ registerState InstanceRegisterState ,
270+ ) InstanceLifecycleState {
271+ switch deployState {
272+ case InstanceDeployStateCrashing , InstanceDeployStateFailed , InstanceDeployStateUnknown , InstanceDeployStateSucceeded :
273+ return InstanceLifecycleStateError
274+ case InstanceDeployStateTerminating :
275+ return InstanceLifecycleStateTerminating
276+ }
277+
278+ if registerState == InstanceRegisterStateRegistered {
279+ if deployState == InstanceDeployStateRunning {
280+ return InstanceLifecycleStateServing
281+ }
282+ return InstanceLifecycleStateError
283+ }
284+
285+ if instance != nil && deployState == InstanceDeployStateRunning && strutil .IsNotBlank (instance .UnregisterTime ) {
286+ return InstanceLifecycleStateDraining
287+ }
288+
289+ switch deployState {
290+ case InstanceDeployStatePending , InstanceDeployStateStarting , InstanceDeployStateRunning :
291+ return InstanceLifecycleStateStarting
292+ default :
293+ return InstanceLifecycleStateUnknown
294+ }
295+ }
296+
297+ func isPodReady (instance * meshproto.Instance ) bool {
298+ for _ , condition := range instance .Conditions {
299+ if condition == nil {
300+ continue
301+ }
302+ if condition .Type == "Ready" {
303+ return condition .Status == "True"
304+ }
305+ }
306+ return false
307+ }
0 commit comments