Skip to content

Add context to actions.

Alejo Carballude requested to merge feature/actions_context into develop

Related tasks

Context

Actions were designed to be generic (i.e. not specific to Cloudsim). The actions framework is missing a mechanism to allow applications to provide application-specific values to jobs.

Change

This MR adds a Context interface to the actions package and changes job functions definitions to now require Context. Contexts are responsible for passing application values to jobs.

The Context interface takes advantage of Go's context.Context interface. Use context.WithValue to set values in the context passed to an action.

Example

//////////////
// Platform //
//////////////

// These constants are defined in the platform 
const (
    ctxPlatform = "platform_platform"
    ctxService = "platform_service"
)

// Job
// This job is defined in the platform and can be used by applications without needing to write code
jobs := Jobs{
    {
        Execute: func(ctx Context, tx *gorm.DB, deployment *Deployment, value interface{}) (interface{}, error) {
                // Get platform from context
                platform, ok := ctx.Value(ctxPlatform).(&Platform)
                if !ok {
                    return nil, errors.new("Platform is required and was not found in the context.")
                }

                // Example returns `value, err`
                return platform.Component().Example(value)
	},
    },
}

/////////////////
// Application //
/////////////////

// Prepare Action
action := NewAction{jobs}

// Initialize Action Service
actionsSvc := actions.NewService()
actionsSvc.RegisterAction("application", "action1", action)

// Create context and set values
ctx := context.Background()
ctx = context.WithValue(ctx, ctxPlatform, &platform)
ctx = context.WithValue(ctx, ctxService, &service)

// Call Action
actionSvc.Execute(ctx, [...])

Note that any information that must be passed between jobs should not be passed using a context, and should be returned by the job instead. This is because return values are automatically persisted, which allows recovering an action after an unexpected stop (e.g. server restart), while any context is lost. The context should only be used to pass application-specific values used by jobs, and can be used to support a simple dependency injection scheme.

Other information

  • Existing JobFunc parameters were kept to reduce the scope of this change. Parameters tx and deployment may be moved to Context in the future to allow greater implementation flexibility and reduce prop drilling.

Additional documentation

Edited by Alejo Carballude

Merge request reports