feat: [CDE-192]: Updating instance state synchronously when calling orchestrator's trigger flows. (#2505)

* feat: [CDE-192]: Updating instance state synchronously when calling orchestrator's trigger flows.
pull/3545/head
Dhruv Dhruv 2024-08-14 11:57:19 +00:00 committed by Harness
parent 236f4dc12a
commit dcf2068873
6 changed files with 63 additions and 68 deletions

View File

@ -137,26 +137,31 @@ func (c *Controller) asyncOperation(
ctxWithTimedOut context.Context,
config types.GitspaceConfig,
action enum.GitspaceActionType,
stateChannel chan enum.GitspaceInstanceStateType,
errChannel chan error,
) {
defer close(stateChannel)
defer close(errChannel)
var orchestrateErr error
var instanceState enum.GitspaceInstanceStateType
switch action {
case enum.GitspaceActionTypeStart:
instanceState, orchestrateErr = c.orchestrator.TriggerStartGitspace(ctxWithTimedOut, config)
config.GitspaceInstance.State = enum.GitspaceInstanceStateStarting
c.updateGitspaceInstance(ctxWithTimedOut, config.GitspaceInstance)
orchestrateErr = c.orchestrator.TriggerStartGitspace(ctxWithTimedOut, config)
case enum.GitspaceActionTypeStop:
instanceState, orchestrateErr = c.orchestrator.TriggerStopGitspace(ctxWithTimedOut, config)
config.GitspaceInstance.State = enum.GitspaceInstanceStateStopping
c.updateGitspaceInstance(ctxWithTimedOut, config.GitspaceInstance)
orchestrateErr = c.orchestrator.TriggerStopGitspace(ctxWithTimedOut, config)
}
if orchestrateErr != nil {
config.GitspaceInstance.State = enum.GitspaceInstanceStateError
c.updateGitspaceInstance(ctxWithTimedOut, config.GitspaceInstance)
errChannel <- fmt.Errorf("failed to start/stop gitspace: %s %w", config.Identifier, orchestrateErr)
}
stateChannel <- instanceState
}
func (c *Controller) submitAsyncOps(
@ -165,15 +170,13 @@ func (c *Controller) submitAsyncOps(
action enum.GitspaceActionType,
) {
errChannel := make(chan error)
stateChannel := make(chan enum.GitspaceInstanceStateType)
submitCtx := context.WithoutCancel(ctx)
ttlExecuteContext, cancel := context.WithTimeout(submitCtx, gitspaceTimedOutInMintues*time.Minute)
go c.asyncOperation(ttlExecuteContext, *config, action, stateChannel, errChannel)
go c.asyncOperation(ttlExecuteContext, *config, action, errChannel)
var err error
var instanceState enum.GitspaceInstanceStateType
go func() {
select {
@ -182,7 +185,6 @@ func (c *Controller) submitAsyncOps(
err = ttlExecuteContext.Err()
}
case err = <-errChannel:
case instanceState = <-stateChannel:
}
if err != nil {
log.Err(err).Msgf("error during async execution for %s", config.GitspaceInstance.Identifier)
@ -194,14 +196,6 @@ func (c *Controller) submitAsyncOps(
}
}
if instanceState == "" {
instanceState = enum.GitspaceInstanceStateError
}
config.GitspaceInstance.State = instanceState
c.updateGitspaceInstance(submitCtx, config.GitspaceInstance)
cancel()
}()
}

View File

@ -58,16 +58,10 @@ func (c *Controller) Delete(
return fmt.Errorf("failed to mark gitspace config as deleted: %w", err)
}
} else {
instanceState, stopErr := c.stopRunningGitspace(ctx, *gitspaceConfig)
stopErr := c.stopRunningGitspace(ctx, *gitspaceConfig)
if stopErr != nil {
return stopErr
}
instance.State = instanceState
err = c.gitspaceInstanceStore.Update(ctx, instance)
if err != nil {
return fmt.Errorf("failed to update instance: %w", err)
}
}
return nil
}
@ -75,10 +69,16 @@ func (c *Controller) Delete(
func (c *Controller) stopRunningGitspace(
ctx context.Context,
config types.GitspaceConfig,
) (enum.GitspaceInstanceStateType, error) {
instanceState, err := c.orchestrator.TriggerDeleteGitspace(ctx, config)
) error {
config.GitspaceInstance.State = enum.GitspaceInstanceStateStopping
c.updateGitspaceInstance(ctx, config.GitspaceInstance)
err := c.orchestrator.TriggerDeleteGitspace(ctx, config)
if err != nil {
return instanceState, err
config.GitspaceInstance.State = enum.GitspaceInstanceStateError
c.updateGitspaceInstance(ctx, config.GitspaceInstance)
return err
}
return instanceState, nil
return nil
}

View File

@ -16,6 +16,7 @@ package events
import (
"context"
"fmt"
"github.com/harness/gitness/events"
"github.com/harness/gitness/types"
@ -41,17 +42,18 @@ func (r *Reporter) EmitGitspaceInfraEvent(
ctx context.Context,
event events.EventType,
payload *GitspaceInfraEventPayload,
) {
) error {
if payload == nil {
return
return fmt.Errorf("payload can not be nil for event type %s", GitspaceInfraEvent)
}
eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, event, payload)
if err != nil {
log.Ctx(ctx).Err(err).Msgf("failed to send %v event", event)
return
return fmt.Errorf("failed to send %+v event", event)
}
log.Ctx(ctx).Debug().Msgf("reported %v event with id '%s'", event, eventID)
return nil
}
func (r *Reader) RegisterGitspaceInfraEvent(

View File

@ -23,7 +23,7 @@ import (
type Orchestrator interface {
// TriggerStartGitspace fetches the infra resources configured for the gitspace and triggers the infra provisioning.
TriggerStartGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
TriggerStartGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) error
// ResumeStartGitspace saves the provisioned infra, resolves the code repo details & creates the Gitspace container.
ResumeStartGitspace(
@ -34,7 +34,7 @@ type Orchestrator interface {
// TriggerStopGitspace stops the Gitspace container and triggers infra deprovisioning to deprovision
// all the infra resources which are not required to restart the Gitspace.
TriggerStopGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
TriggerStopGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) error
// ResumeStopGitspace saves the deprovisioned infra details.
ResumeStopGitspace(
@ -45,7 +45,7 @@ type Orchestrator interface {
// TriggerDeleteGitspace removes the Gitspace container and triggers infra deprovisioning to deprovision
// all the infra resources.
TriggerDeleteGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
TriggerDeleteGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) error
// ResumeDeleteGitspace saves the deprovisioned infra details.
ResumeDeleteGitspace(

View File

@ -79,17 +79,16 @@ func NewOrchestrator(
func (o orchestrator) TriggerStartGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) (enum.GitspaceInstanceStateType, error) {
instanceState := enum.GitspaceInstanceStateError
) error {
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return instanceState, fmt.Errorf("cannot get the infraprovider resource for ID %d: %w",
return fmt.Errorf("cannot get the infraprovider resource for ID %d: %w",
gitspaceConfig.InfraProviderResourceID, err)
}
requiredGitspacePorts, err := o.getPortsRequiredForGitspace(gitspaceConfig)
if err != nil {
return instanceState, fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
return fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningStart)
@ -98,40 +97,36 @@ func (o orchestrator) TriggerStartGitspace(
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningFailed)
return instanceState, fmt.Errorf(
return fmt.Errorf(
"cannot trigger provision infrastructure for ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
instanceState = enum.GitspaceInstanceStateStarting
return instanceState, nil
return nil
}
func (o orchestrator) TriggerStopGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) (enum.GitspaceInstanceStateType, error) {
instanceState := enum.GitspaceInstanceStateError
) error {
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return instanceState, fmt.Errorf(
return fmt.Errorf(
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
requiredGitspacePorts, err := o.getPortsRequiredForGitspace(gitspaceConfig)
if err != nil {
return instanceState, fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
return fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
}
infra, err := o.infraProvisioner.Find(ctx, *infraProviderResource, gitspaceConfig, requiredGitspacePorts)
if err != nil {
return instanceState, fmt.Errorf("cannot find the provisioned infra: %w", err)
return fmt.Errorf("cannot find the provisioned infra: %w", err)
}
err = o.stopGitspaceContainer(ctx, gitspaceConfig, *infra)
if err != nil {
return instanceState, err
return err
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopStart)
@ -140,13 +135,11 @@ func (o orchestrator) TriggerStopGitspace(
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopFailed)
return instanceState, fmt.Errorf(
return fmt.Errorf(
"cannot trigger stop infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
instanceState = enum.GitspaceInstanceStateStopping
return instanceState, nil
return nil
}
func (o orchestrator) stopGitspaceContainer(
@ -216,28 +209,26 @@ func (o orchestrator) stopAndRemoveGitspaceContainer(
func (o orchestrator) TriggerDeleteGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) (enum.GitspaceInstanceStateType, error) {
instanceState := enum.GitspaceInstanceStateError
) error {
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return instanceState, fmt.Errorf(
return fmt.Errorf(
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
requiredGitspacePorts, err := o.getPortsRequiredForGitspace(gitspaceConfig)
if err != nil {
return instanceState, fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
return fmt.Errorf("cannot get the ports required for gitspace during start: %w", err)
}
infra, err := o.infraProvisioner.Find(ctx, *infraProviderResource, gitspaceConfig, requiredGitspacePorts)
if err != nil {
return instanceState, fmt.Errorf("cannot find the provisioned infra: %w", err)
return fmt.Errorf("cannot find the provisioned infra: %w", err)
}
err = o.stopAndRemoveGitspaceContainer(ctx, gitspaceConfig, *infra)
if err != nil {
return instanceState, err
return err
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningStart)
@ -246,12 +237,11 @@ func (o orchestrator) TriggerDeleteGitspace(
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
return instanceState, fmt.Errorf(
return fmt.Errorf(
"cannot trigger deprovision infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
instanceState = enum.GitspaceInstanceStateStopping
return instanceState, nil
return nil
}
func (o orchestrator) emitGitspaceEvent(

View File

@ -109,7 +109,10 @@ func (d DockerProvider) Provision(
Type: enum.InfraEventProvision,
}
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
err = d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
if err != nil {
return fmt.Errorf("error emitting gitspace infra event for provisioning: %w", err)
}
return nil
}
@ -171,7 +174,10 @@ func (d DockerProvider) Stop(ctx context.Context, infra types.Infrastructure) er
Type: enum.InfraEventStop,
}
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
err := d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
if err != nil {
return fmt.Errorf("error emitting gitspace infra event for stopping: %w", err)
}
return nil
}
@ -205,7 +211,10 @@ func (d DockerProvider) Deprovision(ctx context.Context, infra types.Infrastruct
Type: enum.InfraEventDeprovision,
}
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
err = d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
if err != nil {
return fmt.Errorf("error emitting gitspace infra event for deprovisioning: %w", err)
}
return nil
}