-2

I have an application that consumes messages from beanstalkd. You cannot pass context to beanstalkd and you can only use byte slice to send messages. So I converted my context to byte slice.

To propagate from passed context it needs to be converted to context.Context. Is this possible?

// Sending context
ctx := context.Background()

reqBodyBytes := new(bytes.Buffer)
json.NewEncoder(reqBodyBytes).Encode(ctx)

_, err = conn.Put(reqBodyBytes.Bytes(), 1, 0, 120*time.Second)

// Consuming context
_, body, err := conn.Reserve(120 * time.Second)
fmt.Println(string(body))

oldBear
  • 157
  • 2
  • 10
  • 4
    You are not encoding what you think you are encoding. `context.Context` is an interface which has no public implementation types and probably encoding to nonsense. What information are you trying to send? – JimB Nov 01 '21 at 16:07
  • I will start tracing span from context. – oldBear Nov 01 '21 at 16:09
  • 4
    The problem is not converting the byte-slice to a context, the problem is that there is no useful information stored in your byte slice, and the concept of a context is not something which can be directly serialized. – JimB Nov 01 '21 at 16:14

1 Answers1

3

In general it is not possible. context.Context is an interface, the implementations provided by the standard library do not support marshaling the value. For example context.WithValue() returns a context implementation (unexported *context.valueCtx type) that stores the key-value pair in unexported fields.

But since it is an interface type, you may provide implementations that do provide marshaling and unmarshaling capabilities. Although you might run into difficulties marshaling and unmarshaling values of any type if you want to support the context's Context.Value() method too.

In general this isn't a good idea. A context.Context is meant to "carry deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes". It's not something you'd want to persist / transfer.

icza
  • 389,944
  • 63
  • 907
  • 827
  • For the last paragraph: You can make an HTTP request with context? In this case I cannot use normal HTTP request, need to create a span from a specific context. – oldBear Nov 01 '21 at 16:14
  • 3
    sounds like you have an underlying goal that's not expressed in your question - something about passing tracing spans? https://xyproblem.info/ – erik258 Nov 01 '21 at 16:49
  • 1
    @oldBear Given a request, you can create a new request with a given context using `Request.WithContext()`. – icza Nov 01 '21 at 17:00
  • @DanielFarrell, as I stated in previous comments I am trying to keep my trace going in an application that consumes beanstalkd queue. But beanstalkd producer is a different application. What I'm trying is marshalling a struct that contains a context field. – oldBear Nov 01 '21 at 18:30