Go Package context: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 7: Line 7:


=Overview=
=Overview=
<font color=darkkhaki>
One of the key differences between Go and other language is explicit context propagation. Context propagation is a mechanism of propagating an additional call argument, called context, into function calls. There is actually a type called <code>context.Context</code>.
The context is used for:
* Cancellation logic. You can pass a special instance of a context that can get canceled. In that case, all functions you were to call with it would be able to detect this. Can be useful for handling application shutdown or stopping any processing.
* Timeouts. Timeouts can be set for execution, by using the corresponding context functions.
* Propagating extra metadata. Additional key/value pairs can be propagate inside the context. Useful in distributed tracing. This feature should be used sparingly, in exceptional cases.
The context is immutable, but it can be cloned with extra metadata.
Function using context should accept it as their first argument.
</font>
=Organizatorium=
<font color=darkkhaki>
Manage goroutines lifecycles.
If you have a component that blocks for any reason (disk, network IO, user), then it should probably take the context as a first parameter.
<syntaxhighlight lang='go'>
type reportStore interface {
  listTimes(ctx context.Context, ...) (..., error)
  writeFile(ctx context.Context, ...) error
  serveFile(ctx context.Context, ...) error
}
</syntaxhighlight>
Using the value propagation feature of the Context is dubious. Don't use Context.value for stuff that should be regular dependencies between [[Go Component Design|components]]. Use Context.value for data that can be passed to your program in any other way: only data that is request-scoped, stuff that is created at the beginning of a request lifecycle, like request ID, etc. If the information is available when the program starts or at any point prior to when the request starts, do not use context.value. This is the case for database handles, loggers, etc.
* https://go.dev/blog/context
* All functions performing I/O operations must accept context. Why? https://learning.oreilly.com/library/view/microservices-with-go/9781804617007/B18865_02.xhtml#:-:text=all%20functions%20performing
* What is with the _ context.Context https://learning.oreilly.com/library/view/microservices-with-go/9781804617007/B18865_02.xhtml#:-:text=(_%20context.Context
</font>
=TODO=
=TODO=
* https://go.dev/blog/context
* https://go.dev/blog/context

Revision as of 20:41, 8 February 2024

External

Internal

Overview

One of the key differences between Go and other language is explicit context propagation. Context propagation is a mechanism of propagating an additional call argument, called context, into function calls. There is actually a type called context.Context.

The context is used for:

  • Cancellation logic. You can pass a special instance of a context that can get canceled. In that case, all functions you were to call with it would be able to detect this. Can be useful for handling application shutdown or stopping any processing.
  • Timeouts. Timeouts can be set for execution, by using the corresponding context functions.
  • Propagating extra metadata. Additional key/value pairs can be propagate inside the context. Useful in distributed tracing. This feature should be used sparingly, in exceptional cases.

The context is immutable, but it can be cloned with extra metadata.

Function using context should accept it as their first argument.

Organizatorium

Manage goroutines lifecycles.

If you have a component that blocks for any reason (disk, network IO, user), then it should probably take the context as a first parameter.

type reportStore interface {
  listTimes(ctx context.Context, ...) (..., error)
  writeFile(ctx context.Context, ...) error
  serveFile(ctx context.Context, ...) error
}


Using the value propagation feature of the Context is dubious. Don't use Context.value for stuff that should be regular dependencies between components. Use Context.value for data that can be passed to your program in any other way: only data that is request-scoped, stuff that is created at the beginning of a request lifecycle, like request ID, etc. If the information is available when the program starts or at any point prior to when the request starts, do not use context.value. This is the case for database handles, loggers, etc.

TODO