Context isn ' t for cancellation

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

This is a experience report on the use of, and difficulties with, the context.Context facility in Go.

Many authors, including myself, has written about the use of, misuse of, and how they would, in context.Context a future ITE Ration of Go. While opinions differs in many aspects context.Context of, one thing is clear–there are almost unanimous agreement that the Context.WithValue met Hod on the context.Context interface was orthogonal to the type's role as a mechanism to control the lifetime of request scoped Resou RCEs.

Many proposals has emerged to address this apparent overloading of with context.Context a copy on write bag of values. Most approximate thread local storage so is unlikely to is accepted on ideological grounds.

This post explores the relationship between context.Context and lifecycle management and asks the question, is attempts to fix Solving the wrong problem?

Context is a request scoped paradigm

The documentation for the package strongly recommends and that's only for context context.Context request scoped values:

Do not store contexts inside a struct type; Instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter, typically named CTX:

Func dosomething (CTX context. Context, arg arg) error {        //...}

Specifically context.Context values should only live in function arguments, never stored in a field or global. This makes applicable only to the context.Context lifetime of resources in a request ' s scope. Given Go ' s lineage on the server, this is a compelling use case. However, there exist other use cases for cancellation where the lifetime of the resource extends beyond a single request. For example, a background goroutine as part of an agent or pipeline.

Context as a hook for cancellation

The stated goal of the package is context :

Package context defines the context type, which carries deadlines, cancelation signals, and other request-scoped values AC Ross API boundaries and between processes.

Which sounds great, but belies its catch-all nature. is context.Context used in three independent, yet sometimes conflated, scenarios:

    • Cancellation via context.WithCancel .
    • Timeout via context.WithDeadline .
    • A bag of values via context.WithValue .

At any point, a context.Context value can represent any one, or all three of these independent concerns. However, context.Context ' s most important facility, broadcasting a cancellation signal, was incomplete as there is no-to- wait for the signal-be acknowledged.

Looking to the past

As this is a experience report, it would are germane to highlight some actual experience. In Gustavo Niemeyer wrote a package for Goroutine lifecycle management called which are used by Juju for the man tomb Agement of the worker goroutines within the various agents in the Juju system.

tomb.TombS is concerned only with lifecycle management. Importantly, this is a generic notion of a lifecycle, not tied exclusively to a request, or a goroutine. The scope of the resource ' s lifetime is defined simply by holding a reference to the tomb value.

A tomb.Tomb value has three properties:

    1. The ability to signal the owner of the "Tomb to shut" down.
    2. The ability to wait until this signal has been acknowledged.
    3. A-to capture a final error value.

However, tomb.Tomb S has one drawback, they cannot be shared across multiple goroutines. Consider this prototypical network server where a tomb.Tomb cannot replace the use of sync.WaitGroup .

Func Serve (l net. Listener) Error {        var wg sync. Waitgroup        var conn net. Conn        var err error        for {                Conn, err = l.accept ()                if err! = nil {break                }                WG. ADD (1)                go func (c net. Conn) {                        defer WG. Done ()                        handle (c)                } (conn)        }        WG. Wait ()        return err}

To is fair, context.Context cannot do this either as it provides no built in mechanism to acknowledge cancellation. What's needed is a form sync.WaitGroup of this allows cancellation, as well as waiting for it participants to call wg.Done .

Context should become, well, just context

The purpose of the context.Context type is in it ' s name:

context/kɒntɛkst/ noun
The circumstances that form the setting for a event, statement, or idea, and in terms of which it can be fully understood .

I propose context.Context becomes just that; a request scoped association list of copy on write values.

Decoupling lifetime management from as context.Context a store of request scoped values would hopefully highlight that request Contex T and lifecycle management are orthogonal concerns.

Best of all, we don't need to wait til Go 2.0 to explore these ideas like Gustavo ' s package tomb .

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.