{"action":"closed","issue":{"url":"https://api.github.com/repos/aws/aws-sdk-go/issues/75","labels_url":"https://api.github.com/repos/aws/aws-sdk-go/issues/75/labels{/name}","comments_url":"https://api.github.com/repos/aws/aws-sdk-go/issues/75/comments","events_url":"https://api.github.com/repos/aws/aws-sdk-go/issues/75/events","html_url":"https://github.com/aws/aws-sdk-go/issues/75","id":56051063,"number":75,"title":"Support context pattern","user":{"login":"justonia","id":89791,"avatar_url":"https://avatars.githubusercontent.com/u/89791?v=3","gravatar_id":"","url":"https://api.github.com/users/justonia","html_url":"https://github.com/justonia","followers_url":"https://api.github.com/users/justonia/followers","following_url":"https://api.github.com/users/justonia/following{/other_user}","gists_url":"https://api.github.com/users/justonia/gists{/gist_id}","starred_url":"https://api.github.com/users/justonia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justonia/subscriptions","organizations_url":"https://api.github.com/users/justonia/orgs","repos_url":"https://api.github.com/users/justonia/repos","events_url":"https://api.github.com/users/justonia/events{/privacy}","received_events_url":"https://api.github.com/users/justonia/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/aws/aws-sdk-go/labels/feature%20request","name":"feature request","color":"bfe5bf"},{"url":"https://api.github.com/repos/aws/aws-sdk-go/labels/review%20needed","name":"review needed","color":"207de5"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-01-30T16:04:18Z","updated_at":"2015-08-05T22:25:40Z","closed_at":"2015-08-05T22:25:40Z","body":"See this blog article:\r\n\r\nhttps://blog.golang.org/context\r\n\r\nWe use this heavily in all aspects of our SOA, and it allows us to inject request scoped parameters to systems that need them to provide useful information -- such as logging or in-memory caches. Here is a drastically simplified example:\r\n\r\n    type key int\r\n    const LoggerKey key = 0\r\n    const RequestIdKey key = 1\r\n    const MethodNameKey key = 2\r\n    \r\n    type Logger interface {\r\n        Debug(ctx context.Context, message, args ...interface{})\r\n    }    \r\n\r\n    // alternatively the context interface could have the log methods on them to avoid this step\r\n    func LoggerFrom(ctx context.Context) Logger {\r\n        if logger, ok := ctx.Value(LoggerKey).(Logger); ok {\r\n            return logger\r\n        } else {\r\n            return nullLogger\r\n        }\r\n    }\r\n\r\n    ctx := context.WithCancel(context.Background())\r\n    ctx = context.WithValue(ctx, RequestIdKey, uuid.NewV4())\r\n    ctx = context.WithValue(ctx, LoggerKey, myLogger)\r\n    \r\n    someFrontendMethod(ctx, other, arguments)\r\n\r\n    ...\r\n\r\n    func someFrontendMethod(ctx context.Context, other int, arguments string) {\r\n        ctx = context.WithValue(ctx, MethodNameKey, \"someFrontendMethod\")\r\n        result, err := aws.DynamoDb().Get(ctx, ...) \r\n        ...\r\n    }\r\n\r\n    // totally made up interface, not implying this should be the real AWS one\r\n    func (d *DynamoDb) Get(ctx context.Context, some int, args string) (*Result, error) {\r\n        LoggerFrom(ctx).Debug(ctx, \"dynamodb.get - starting request\")\r\n        ...\r\n    }\r\n\r\nThis would then output something like:\r\n    \r\n    [DEBUG] [requestId=5f0712749191adda1079e71c2403ec24d65ebf32] someFrontendMethod: dynamodb.get - starting request\r\n\r\nAdditionally, in the first method, you would be able to timeout the call to someFrontendMethod by closing the Done channel on the context. Depending upon how much of the callstack is using the context, every goroutine underneath it would be notified of the cancelled context and abort as soon as possible. In the case of the AWS lib, this could be used to abort an exponential backoff algorithm that is currently sleeping without the caller of the lib having to cancel manually somehow.\r\n    \r\n    \r\n\t\t\t\r\n\r\n"}}