>
> What does "SomeOtherFunc" need with the statefun context
>
> I think it's hard to answer this question, in a general sense. Depending
> on what is being done, it might need to read a value from statefun Storage,
> write one back, etc.


To me, this indicates that the context is responsible for too much and
cannot properly be passed to functions with a distinct purpose. I think the
`context.Context` shares this design but gets away with it because its
functionality is so constrained and generic (deadlines, cancellation,
values – that's it).
This is getting away from the original question of the thread, but I bring
it up to suggest that we take a more holistic look at the statefun Context
interface and go with a simpler solution (either the `WithContext` method
or Till's suggestion) to avoid further muddying the possible uses. WDYT?

Austin

On Tue, Feb 22, 2022 at 1:14 PM Galen Warren <ga...@cvillewarrens.com>
wrote:

>  One place we could look is the `net/http` Request, which has a
>> `WithContext` method[1] that seems to expose the behavior we're looking
>> for.
>>
>
> I considered something similar, too, and upon another look, maybe I
> dismissed it too quickly. The concern I had was that an implementation that
> simply updated the internal context.Context of an existing statefun.Context
> would violate the assumption that contexts are immutable. However, if the
> implementation copied all the statefun.Context parts to a new stateful
> context structure and associated them with the passed-in context.Context,
> that seems like it could work. There's a sync.Mutex in the statefun context
> structure that we'd have to be careful about.
>
>
>> What does "SomeOtherFunc" need with the statefun context?
>>
>
> I think it's hard to answer this question, in a general sense. Depending
> on what is being done, it might need to read a value from statefun Storage,
> write one back, etc.
>
>  The solution that Till proposed seems to fit the example you gave quite
>> well, no?
>>
>
> Yes, this would work, but I agree with Till that this is not a perfect
> solution. In the event that downstream code needs to access both the
> context.Context and the statefun.Context, one would be passing two contexts
> around, but it would be important not to use the statefun.Context one for
> any context values. That's workable, but it seems a bit clumsy to me.
>
> On Tue, Feb 22, 2022 at 12:47 PM Austin Cawley-Edwards <
> austin.caw...@gmail.com> wrote:
>
>> Hey,
>>
>> Sorry for the late response – been off the ML for a few days.
>>
>> I am not too familiar with other Go libs that use a custom context. One
>> place we could look is the `net/http` Request, which has a `WithContext`
>> method[1] that seems to expose the behavior we're looking for. That could
>> be added to the statefun context package as a standalone method (e.g.
>> statefun.WithContext(sCtx Context, ctx context.Context)), but would only
>> work for the private implementation. I think the statefun Context type
>> being an interface instead of a concrete type complicates and restricts us
>> a bit here.
>>
>> I guess I am not fully understanding why the statefun Context needs to be
>> used so far down the line. The solution that Till proposed seems to fit the
>> example you gave quite well, no?
>>
>> func (f *MyFunc) Invoke(ctx statefun.Context, message statefun.Message)
>> error {
>>    logger := NewLogger()
>>    downCtx := context.WithValue(ctx, "logger", logger)
>>    return SomeOtherFunc(downCtx)
>> }
>>
>> func SomeOtherFunc(ctx context.Context) error {
>>    logger := ctx.Value("logger")
>>    return nil
>> }
>>
>> What does "SomeOtherFunc" need with the statefun context? I think that
>> would help me, at least, understand the role of the statefun context.
>>
>>  I'm curious what you would think about an approach that kept everything
>>> as-is, by default, but allowed for a separated context and runtime in the
>>> Invoke method, on an opt-in basis, via an adapter?
>>>
>>
>> I am not involved in statefun really, but IMO that seems like quite a lot
>> of overhead to just pass values via the context. Perhaps we should consider
>> decomposing the statefun context itself so pieces of functionality can be
>> passed around more easily?
>>
>> Best,
>> Austin
>>
>>
>> [1]: https://pkg.go.dev/net/http#Request.WithContext
>>
>>
>> On Tue, Feb 22, 2022 at 10:51 AM Galen Warren <ga...@cvillewarrens.com>
>> wrote:
>>
>>> Thanks, Seth.
>>>
>>> I'm curious what you would think about an approach that kept everything
>>> as-is, by default, but allowed for a separated context and runtime in the
>>> Invoke method, on an opt-in basis, via an adapter?
>>>
>>> On Tue, Feb 22, 2022 at 10:28 AM Seth Wiesman <sjwies...@gmail.com>
>>> wrote:
>>>
>>>> Hi all,
>>>>
>>>> I believe the discussion revolved around:
>>>>
>>>> 1. fewer parameters
>>>> 2. better aligned with other language sdks
>>>> 3. we found precedent in other libraries (apologies this was long enough
>>>> ago I cannot remember which ones, I'm looking through old discussions
>>>> now)
>>>>
>>>> I would in general champion a solution that keeps the SDKs looking
>>>> similar
>>>> across languages. A big part of statefun's positioning in the market is
>>>> the
>>>> polyglot nature and making the transition between languages as seamless
>>>> as
>>>> possible is very important.
>>>>
>>>> Seth
>>>>
>>>>
>>>> On Tue, Feb 22, 2022 at 4:33 AM Till Rohrmann <trohrm...@apache.org>
>>>> wrote:
>>>>
>>>> > Hi Galen,
>>>> >
>>>> > Thanks for explaining the problems with the current design. I think
>>>> I've
>>>> > already learned quite a bit wrt Go thanks to you :-)
>>>> >
>>>> > From what you describe it seems indeed a bit restrictive to let the
>>>> > statefun.Context contain the context.Context w/o giving access to it.
>>>> Maybe @Seth
>>>> > Wiesman <sjwies...@gmail.com> can elaborate a bit more on the design
>>>> > decisions to make sure that we have the full picture.
>>>> >
>>>> > As a cheap workaround you could create a context.Context object by
>>>> calling
>>>> >
>>>> https://github.com/knative/pkg/blob/d48172451966/logging/logger.go#L45
>>>> on
>>>> > the statefun.Context and then pass this Context instance to the
>>>> downstream
>>>> > function. But I agree that this is not the perfect solution.
>>>> >
>>>> > How do other libraries handle this situation if they offer a custom
>>>> > Context type? Maybe @Austin Cawley-Edwards <austin.caw...@gmail.com>
>>>> you
>>>> > have an opinion on the matter.
>>>> >
>>>> > Cheers,
>>>> > Till
>>>> >
>>>> > On Mon, Feb 21, 2022 at 7:42 PM Galen Warren <ga...@cvillewarrens.com
>>>> >
>>>> > wrote:
>>>> >
>>>> >> So, upon further fiddling, I think it would be possible to keep full
>>>> >> backward compatibility and add the option for someone to use an
>>>> Invoke
>>>> >> method with a separate context.Context and statefun.Runtime, via an
>>>> >> adapter, if direct manipulation of the context.Context is needed. So,
>>>> >> basically, the idea would be to let the user choose the form of the
>>>> Invoke
>>>> >> method, with the default behavior remaining the same as now.
>>>> >>
>>>> >> This would require:
>>>> >>
>>>> >>    - Recreating the Runtime interface (all methods currently defined
>>>> on
>>>> >>    Context except not embedding context.Context) and embedding it in
>>>> the
>>>> >>    statefun.Context interface, so that statefun.Context remains
>>>> >> effectively
>>>> >>    unchanged
>>>> >>    - Add StatefulFunctionV2 and StatefunFunctionV2Pointer to support
>>>> the
>>>> >>    new signature with separate context and runtime
>>>> >>    - Add StatefulFunctionV2Adapter to wrap a StatefulFunctionV2 and
>>>> expose
>>>> >>    it as a StatefulFunction. The statefun.Context would get split
>>>> into a
>>>> >>    context.Context and a statefun.Runtime here in order to call the
>>>> new
>>>> >>    signature.
>>>> >>
>>>> >> Thoughts? I'd be happy to take a crack at it.
>>>> >>
>>>> >>
>>>> >> On Mon, Feb 21, 2022 at 12:06 PM Galen Warren <
>>>> ga...@cvillewarrens.com>
>>>> >> wrote:
>>>> >>
>>>> >> > Was the reason to combine them the desire to have two parameters
>>>> vs.
>>>> >> > three, or was there another motivation?
>>>> >> >
>>>> >> > On Mon, Feb 21, 2022 at 12:02 PM Seth Wiesman <sjwies...@gmail.com
>>>> >
>>>> >> wrote:
>>>> >> >
>>>> >> >> FWIW I received a lot of early feedback explicitly asking me to
>>>> couple
>>>> >> the
>>>> >> >> statefun specific operations with the Context (why the runtime
>>>> type
>>>> >> went
>>>> >> >> away).
>>>> >> >>
>>>> >> >> Seth
>>>> >> >>
>>>> >> >> On Mon, Feb 21, 2022 at 10:32 AM Galen Warren <
>>>> ga...@cvillewarrens.com
>>>> >> >
>>>> >> >> wrote:
>>>> >> >>
>>>> >> >> > Thanks for looking into this!
>>>> >> >> >
>>>> >> >> > The issue I think we'd run into with your proposal is that,
>>>> often,
>>>> >> >> > libraries use non-exported types for context keys. Here is an
>>>> example
>>>> >> >> > <
>>>> >>
>>>> https://github.com/knative/pkg/blob/d48172451966/logging/logger.go#L45
>>>> >> >> >;
>>>> >> >> > in this case, the non-exported loggerKey{} is used as the key,
>>>> inside
>>>> >> >> the
>>>> >> >> > exported WithLogger function. The key that would have to be
>>>> supplied
>>>> >> to
>>>> >> >> the
>>>> >> >> > proposed Value and WithValue functions would not be accessible
>>>> in
>>>> >> this
>>>> >> >> > case.
>>>> >> >> >
>>>> >> >> > Honestly, if *everything *were on the table -- and understand
>>>> it very
>>>> >> >> well
>>>> >> >> > might not be -- I'd suggest decoupling the Golang
>>>> context.Context and
>>>> >> >> the
>>>> >> >> > statefun Context, i.e. have two separate parameters to
>>>> >> >> > StatefulFunction.Invoke representing Golang context and statefun
>>>> >> >> > operations. This is actually how things were in an earlier
>>>> version of
>>>> >> >> the
>>>> >> >> > Golang SDK; the first parameter to Invoke was the plain-vanilla
>>>> >> >> > context.Context and a separate parameter provided the statefun
>>>> >> >> "runtime".
>>>> >> >> > So maybe something like this:
>>>> >> >> >
>>>> >> >> > >
>>>> >> >> > > type StatefulFunction interface {
>>>> >> >> > > Invoke(ctx context.Context, runtime Runtime, message Message)
>>>> error
>>>> >> >> > > }
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > ... instead of the current:
>>>> >> >> >
>>>> >> >> > type StatefulFunction interface {
>>>> >> >> > > Invoke(ctx Context, message Message) error
>>>> >> >> > > }
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > ... where Runtime would be everything currently in
>>>> statefun.Context,
>>>> >> >> except
>>>> >> >> > the context.Context part. This would allow context.Context to be
>>>> >> >> > manipulated and passed around normally.
>>>> >> >> >
>>>> >> >> > I think this could potentially be done in a backward-compatible
>>>> way,
>>>> >> >> with a
>>>> >> >> > new set of types and methods, e.g. StatefulFunctionV2,
>>>> >> >> > StatefufFunctionSpecV2, StatefulFunctions.WithSpecV2, etc. Or it
>>>> >> could
>>>> >> >> be
>>>> >> >> > done in an almost backward-compatible way, by changing the
>>>> existing
>>>> >> >> > StatefulFunction, StatefulFunctionSpec,
>>>> StatefulFunctions.WithSpec
>>>> >> and
>>>> >> >> > providing an adapter for people who want to continue to use the
>>>> >> >> > two-parameter version of Invoke.
>>>> >> >> >
>>>> >> >> > If those kinds of changes are a non-starter, then IMO the next
>>>> best
>>>> >> >> option
>>>> >> >> > would be adding something like:
>>>> >> >> >
>>>> >> >> > PrepareContext func(ctx statefun.Context) context.Context
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > ... to StatefulFunctionSpec to allow a one-time customization
>>>> of the
>>>> >> >> > underlying context at the beginning of a stateful function
>>>> >> invocation.
>>>> >> >> That
>>>> >> >> > would cover a lot of use cases.
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > On Mon, Feb 21, 2022 at 3:06 AM Till Rohrmann <
>>>> trohrm...@apache.org>
>>>> >> >> > wrote:
>>>> >> >> >
>>>> >> >> > > Thanks a lot for clarifying the problem. I think I now
>>>> understand
>>>> >> the
>>>> >> >> > > problem. As you've probably figured out, I have no clue about
>>>> Go
>>>> >> and
>>>> >> >> > > its usage of the Context type.
>>>> >> >> > >
>>>> >> >> > > After looking into it a bit I was wondering whether we can't
>>>> >> follow a
>>>> >> >> > > similar route as it is done for the Context type. By adding
>>>> >> something
>>>> >> >> > like
>>>> >> >> > >
>>>> >> >> > > type valueCtx struct {
>>>> >> >> > > Context
>>>> >> >> > > key, val interface{}
>>>> >> >> > > }
>>>> >> >> > >
>>>> >> >> > > func (c *valueCtx) Value(key interface{}) interface{} {
>>>> >> >> > > if c.key == key {
>>>> >> >> > > return c.val
>>>> >> >> > > }
>>>> >> >> > > return c.Context.Value(key)
>>>> >> >> > > }
>>>> >> >> > >
>>>> >> >> > > func WithValue(parent Context, key, val interface{}) Context {
>>>> >> >> > > if parent == nil {
>>>> >> >> > > panic("cannot create context from nil parent")
>>>> >> >> > > }
>>>> >> >> > > if key == nil {
>>>> >> >> > > panic("nil key")
>>>> >> >> > > }
>>>> >> >> > > return &valueCtx{parent, key, val}
>>>> >> >> > > }
>>>> >> >> > >
>>>> >> >> > > to the statefun/context.go we would allow to extend a Statefun
>>>> >> context
>>>> >> >> > with
>>>> >> >> > > values w/o changing the underlying instance. If
>>>> statefun.Context is
>>>> >> >> not
>>>> >> >> > > needed, then there is already the option to unwrap the
>>>> >> context.Context
>>>> >> >> > and
>>>> >> >> > > to extend it with values and then pass on this instance. But
>>>> maybe
>>>> >> >> this
>>>> >> >> > is
>>>> >> >> > > no idiomatic Go. Let me know what you think.
>>>> >> >> > >
>>>> >> >> > > Cheers,
>>>> >> >> > > Till
>>>> >> >> > >
>>>> >> >> > > On Fri, Feb 18, 2022 at 7:01 PM Galen Warren <
>>>> >> ga...@cvillewarrens.com
>>>> >> >> >
>>>> >> >> > > wrote:
>>>> >> >> > >
>>>> >> >> > > > Hmm ... a downside to my proposal is that Go contexts are
>>>> >> supposed
>>>> >> >> to
>>>> >> >> > be
>>>> >> >> > > > immutable, i.e. when adding a custom value to a context, a
>>>> new
>>>> >> >> context
>>>> >> >> > is
>>>> >> >> > > > created with the new value and the old context isn't
>>>> changed.
>>>> >> >> Changing
>>>> >> >> > > the
>>>> >> >> > > > context.Context associated with the statefun.Context sort
>>>> of goes
>>>> >> >> > against
>>>> >> >> > > > the spirit of that, i.e. a consumer of statefun.Context
>>>> could see
>>>> >> >> > custom
>>>> >> >> > > > values change unexpectedly if another consumer of the same
>>>> >> >> > > statefun.Context
>>>> >> >> > > > modified the underlying context.Context.
>>>> >> >> > > >
>>>> >> >> > > > To avoid that, I think we'd be back to having some
>>>> mechanism to
>>>> >> >> > customize
>>>> >> >> > > > the underlying context.Context once, when the
>>>> statefun.Context is
>>>> >> >> > created
>>>> >> >> > > > at the beginning of a stateful function invocation. Adding a
>>>> >> field
>>>> >> >> > like:
>>>> >> >> > > >
>>>> >> >> > > > PrepareContext func(ctx statefun.Context) context.Context
>>>> >> >> > > >
>>>> >> >> > > > ... to the StatefulFunctionSpec struct could accomplish
>>>> that,
>>>> >> i.e.
>>>> >> >> if
>>>> >> >> > > > PrepareContext were supplied, the context could be
>>>> customized
>>>> >> once
>>>> >> >> at
>>>> >> >> > the
>>>> >> >> > > > start of a function invocation and then left immutable
>>>> after that
>>>> >> >> > point.
>>>> >> >> > > >
>>>> >> >> > > > (Using statefun.Context as the input is deliberate here, in
>>>> >> order to
>>>> >> >> > > allow
>>>> >> >> > > > the context.Context to be populated using values from the
>>>> >> >> > > statefun.Context,
>>>> >> >> > > > for example the function id).
>>>> >> >> > > >
>>>> >> >> > > >
>>>> >> >> > > >
>>>> >> >> > > >
>>>> >> >> > > >
>>>> >> >> > > >
>>>> >> >> > > > On Fri, Feb 18, 2022 at 11:34 AM Galen Warren <
>>>> >> >> ga...@cvillewarrens.com
>>>> >> >> > >
>>>> >> >> > > > wrote:
>>>> >> >> > > >
>>>> >> >> > > > > An example of passing it around would be:
>>>> >> >> > > > >
>>>> >> >> > > > > func (f *MyFunc) Invoke(ctx statefun.Context, message
>>>> >> >> > statefun.Message)
>>>> >> >> > > > > error {
>>>> >> >> > > > >
>>>> >> >> > > > >     logger := NewLogger()
>>>> >> >> > > > >     ctx.SetContext(ctxzap.ToContext(ctx, logger))
>>>> >> >> > > > >
>>>> >> >> > > > >     return SomeOtherFunc(ctx)
>>>> >> >> > > > > }
>>>> >> >> > > > >
>>>> >> >> > > > > func SomeOtherFunc(ctx context.Context) error {
>>>> >> >> > > > >
>>>> >> >> > > > >     logger := ctxzap.Extract(ctx)
>>>> >> >> > > > >     logger.Info(...)
>>>> >> >> > > > >
>>>> >> >> > > > >     return nil
>>>> >> >> > > > > }
>>>> >> >> > > > >
>>>> >> >> > > > > This would also work with further nested calls, so long
>>>> as the
>>>> >> >> > context
>>>> >> >> > > is
>>>> >> >> > > > > passed to them.
>>>> >> >> > > > >
>>>> >> >> > > > > On Fri, Feb 18, 2022 at 11:23 AM Galen Warren <
>>>> >> >> > ga...@cvillewarrens.com
>>>> >> >> > > >
>>>> >> >> > > > > wrote:
>>>> >> >> > > > >
>>>> >> >> > > > >> Ha, our emails keep passing.
>>>> >> >> > > > >>
>>>> >> >> > > > >> I've been playing around with options locally, and the
>>>> >> SetContext
>>>> >> >> > > option
>>>> >> >> > > > >> seems to be the most flexible (and non-breaking), imo.
>>>> >> >> > > > >>
>>>> >> >> > > > >> The implementation would be trivial, just add:
>>>> >> >> > > > >>
>>>> >> >> > > > >> SetContext(ctx context.Context)
>>>> >> >> > > > >>
>>>> >> >> > > > >> ... to the statefun.Context interface, which is
>>>> implemented
>>>> >> as:
>>>> >> >> > > > >>
>>>> >> >> > > > >> func (s *statefunContext) SetContext(ctx
>>>> context.Context) {
>>>> >> >> > > > >> s.Context = ctx
>>>> >> >> > > > >> }
>>>> >> >> > > > >>
>>>> >> >> > > > >>
>>>> >> >> > > > >>
>>>> >> >> > > > >>
>>>> >> >> > > > >> On Fri, Feb 18, 2022 at 11:18 AM Austin Cawley-Edwards <
>>>> >> >> > > > >> austin.caw...@gmail.com> wrote:
>>>> >> >> > > > >>
>>>> >> >> > > > >>> It would be helpful to have a small example though, if
>>>> you
>>>> >> have
>>>> >> >> on
>>>> >> >> > > > Galen,
>>>> >> >> > > > >>> to see how you're passing it around.
>>>> >> >> > > > >>>
>>>> >> >> > > > >>> On Fri, Feb 18, 2022 at 11:10 AM Austin Cawley-Edwards <
>>>> >> >> > > > >>> austin.caw...@gmail.com> wrote:
>>>> >> >> > > > >>>
>>>> >> >> > > > >>> > Looking through the statefun Context interface, it
>>>> indeed
>>>> >> >> doesn't
>>>> >> >> > > > give
>>>> >> >> > > > >>> > access to the underlying context.Context and the only
>>>> >> >> > > implementation
>>>> >> >> > > > is
>>>> >> >> > > > >>> > package-private [1]. I don't think there would be a
>>>> way to
>>>> >> >> update
>>>> >> >> > > the
>>>> >> >> > > > >>> > statfun.Context interface without introducing breaking
>>>> >> >> changes,
>>>> >> >> > but
>>>> >> >> > > > if
>>>> >> >> > > > >>> we
>>>> >> >> > > > >>> > were to make that implementation public, that might
>>>> be a
>>>> >> >> stopgap
>>>> >> >> > > > >>> solution.
>>>> >> >> > > > >>> > e.g.,
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > ```
>>>> >> >> > > > >>> > type StatefunContext struct {
>>>> >> >> > > > >>> > // expose embedded context
>>>> >> >> > > > >>> > context.Context
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > // make the mutext private
>>>> >> >> > > > >>> > mu sync.Mutex
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > // keep internals private
>>>> >> >> > > > >>> > self     Address
>>>> >> >> > > > >>> > caller   *Address
>>>> >> >> > > > >>> > storage  *storage
>>>> >> >> > > > >>> > response *protocol.FromFunction_InvocationResponse
>>>> >> >> > > > >>> > }
>>>> >> >> > > > >>> > ```
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > You could then do a type assertion in the handlers
>>>> for this
>>>> >> >> type
>>>> >> >> > of
>>>> >> >> > > > >>> > context, and modify the context on it directly. It
>>>> would
>>>> >> be a
>>>> >> >> bit
>>>> >> >> > > > >>> ugly, but
>>>> >> >> > > > >>> > may work.
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > ```
>>>> >> >> > > > >>> > func (s aFunc) Invoke(ctx Context, message Message)
>>>> error {
>>>> >> >> > > > >>> >   if sCtx, ok := ctx.(*statefun.StatefunContext); ok {
>>>> >> >> > > > >>> >     sCtx.Context = context.WithValue(sCtx.Context,
>>>> >> "logger",
>>>> >> >> > > aLogger)
>>>> >> >> > > > >>> >   }
>>>> >> >> > > > >>> >   // ...
>>>> >> >> > > > >>> > }
>>>> >> >> > > > >>> > ```
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > Let me know what you all think,
>>>> >> >> > > > >>> > Austin
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > [1]:
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>>
>>>> >> >> > > >
>>>> >> >> > >
>>>> >> >> >
>>>> >> >>
>>>> >>
>>>> https://github.com/apache/flink-statefun/blob/1dfe226d85fea05a46c8ffa688175b4c0f2d4900/statefun-sdk-go/v3/pkg/statefun/context.go#L66-L73
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > On Fri, Feb 18, 2022 at 11:03 AM Galen Warren <
>>>> >> >> > > > ga...@cvillewarrens.com
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> > wrote:
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>> >> Sorry Austin, I didn't see your response before I
>>>> replied.
>>>> >> >> Yes,
>>>> >> >> > > > we're
>>>> >> >> > > > >>> >> saying the same thing.
>>>> >> >> > > > >>> >>
>>>> >> >> > > > >>> >> On Fri, Feb 18, 2022 at 10:56 AM Austin
>>>> Cawley-Edwards <
>>>> >> >> > > > >>> >> austin.caw...@gmail.com> wrote:
>>>> >> >> > > > >>> >>
>>>> >> >> > > > >>> >> > Hey all, jumping in. This makes sense to me – for
>>>> >> instance
>>>> >> >> to
>>>> >> >> > > > >>> attach a
>>>> >> >> > > > >>> >> > logger with some common metadata, e.g trace ID for
>>>> the
>>>> >> >> > request?
>>>> >> >> > > > >>> This is
>>>> >> >> > > > >>> >> > common in go to add arbitrary items without
>>>> updating the
>>>> >> >> > method
>>>> >> >> > > > >>> >> signatures,
>>>> >> >> > > > >>> >> > similar to thread local storage in Java.
>>>> >> >> > > > >>> >> >
>>>> >> >> > > > >>> >> > On Fri, Feb 18, 2022 at 10:53 AM Till Rohrmann <
>>>> >> >> > > > >>> trohrm...@apache.org>
>>>> >> >> > > > >>> >> > wrote:
>>>> >> >> > > > >>> >> >
>>>> >> >> > > > >>> >> > > Thanks for the clarification Galen. If you call
>>>> the
>>>> >> >> other Go
>>>> >> >> > > > >>> >> functions,
>>>> >> >> > > > >>> >> > > then you could also pass the other values as
>>>> separate
>>>> >> >> > > arguments
>>>> >> >> > > > to
>>>> >> >> > > > >>> >> these
>>>> >> >> > > > >>> >> > > functions, can't you?
>>>> >> >> > > > >>> >> > >
>>>> >> >> > > > >>> >> > > Cheers,
>>>> >> >> > > > >>> >> > > Till
>>>> >> >> > > > >>> >> > >
>>>> >> >> > > > >>> >> > > On Fri, Feb 18, 2022 at 3:31 PM Galen Warren <
>>>> >> >> > > > >>> ga...@cvillewarrens.com
>>>> >> >> > > > >>> >> >
>>>> >> >> > > > >>> >> > > wrote:
>>>> >> >> > > > >>> >> > >
>>>> >> >> > > > >>> >> > > > The former.
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > > > I think there's potential for confusion here
>>>> because
>>>> >> >> we're
>>>> >> >> > > > >>> using the
>>>> >> >> > > > >>> >> > > > word *function
>>>> >> >> > > > >>> >> > > > *in a couple of senses. One sense is a
>>>> *stateful
>>>> >> >> > function*;
>>>> >> >> > > > >>> another
>>>> >> >> > > > >>> >> > sense
>>>> >> >> > > > >>> >> > > > is a *Go function*.
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > > > What I'm looking to do is to put values in the
>>>> >> Context
>>>> >> >> so
>>>> >> >> > > that
>>>> >> >> > > > >>> >> > downstream
>>>> >> >> > > > >>> >> > > > Go functions that receive the context can
>>>> access
>>>> >> those
>>>> >> >> > > values.
>>>> >> >> > > > >>> Those
>>>> >> >> > > > >>> >> > > > downstream Go functions would be called during
>>>> one
>>>> >> >> > > invocation
>>>> >> >> > > > >>> of the
>>>> >> >> > > > >>> >> > > > stateful function.
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > > > On Fri, Feb 18, 2022 at 6:48 AM Till Rohrmann <
>>>> >> >> > > > >>> trohrm...@apache.org
>>>> >> >> > > > >>> >> >
>>>> >> >> > > > >>> >> > > > wrote:
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > > > > Hi Galen,
>>>> >> >> > > > >>> >> > > > >
>>>> >> >> > > > >>> >> > > > > Am I understanding it correctly, that you
>>>> would
>>>> >> like
>>>> >> >> to
>>>> >> >> > > set
>>>> >> >> > > > >>> some
>>>> >> >> > > > >>> >> > values
>>>> >> >> > > > >>> >> > > > in
>>>> >> >> > > > >>> >> > > > > the Context of function A that is then
>>>> accessible
>>>> >> in
>>>> >> >> a
>>>> >> >> > > > >>> downstream
>>>> >> >> > > > >>> >> > call
>>>> >> >> > > > >>> >> > > of
>>>> >> >> > > > >>> >> > > > > function B? Or would you like to set a value
>>>> that
>>>> >> is
>>>> >> >> > > > >>> accessible
>>>> >> >> > > > >>> >> once
>>>> >> >> > > > >>> >> > > > > function A is called again (w/ or w/o the
>>>> same
>>>> >> id)?
>>>> >> >> > > > >>> >> > > > >
>>>> >> >> > > > >>> >> > > > > Cheers,
>>>> >> >> > > > >>> >> > > > > Till
>>>> >> >> > > > >>> >> > > > >
>>>> >> >> > > > >>> >> > > > > On Thu, Feb 17, 2022 at 10:59 PM Galen
>>>> Warren <
>>>> >> >> > > > >>> >> > ga...@cvillewarrens.com
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > > > > wrote:
>>>> >> >> > > > >>> >> > > > >
>>>> >> >> > > > >>> >> > > > > > Also, a potentially simpler way to support
>>>> this
>>>> >> >> would
>>>> >> >> > be
>>>> >> >> > > > to
>>>> >> >> > > > >>> add
>>>> >> >> > > > >>> >> a
>>>> >> >> > > > >>> >> > > > > > SetContext method to the statefun.Context
>>>> >> >> interface,
>>>> >> >> > and
>>>> >> >> > > > >>> have it
>>>> >> >> > > > >>> >> > > assign
>>>> >> >> > > > >>> >> > > > > the
>>>> >> >> > > > >>> >> > > > > > wrapped context. This would not require
>>>> changes
>>>> >> to
>>>> >> >> the
>>>> >> >> > > > >>> function
>>>> >> >> > > > >>> >> > spec,
>>>> >> >> > > > >>> >> > > > or
>>>> >> >> > > > >>> >> > > > > > anything else, and would be more flexible.
>>>> >> >> > > > >>> >> > > > > >
>>>> >> >> > > > >>> >> > > > > > On Thu, Feb 17, 2022 at 1:05 PM Galen
>>>> Warren <
>>>> >> >> > > > >>> >> > > ga...@cvillewarrens.com>
>>>> >> >> > > > >>> >> > > > > > wrote:
>>>> >> >> > > > >>> >> > > > > >
>>>> >> >> > > > >>> >> > > > > > > Thanks for the quick reply!
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > > What I'm trying to do is put some things
>>>> into
>>>> >> the
>>>> >> >> > > > context
>>>> >> >> > > > >>> so
>>>> >> >> > > > >>> >> that
>>>> >> >> > > > >>> >> > > > > they're
>>>> >> >> > > > >>> >> > > > > > > available in downstream calls, perhaps in
>>>> >> methods
>>>> >> >> > with
>>>> >> >> > > > >>> pointer
>>>> >> >> > > > >>> >> > > > > receivers
>>>> >> >> > > > >>> >> > > > > > to
>>>> >> >> > > > >>> >> > > > > > > the function struct (MyFunc) but also
>>>> perhaps
>>>> >> in
>>>> >> >> > > methods
>>>> >> >> > > > >>> that
>>>> >> >> > > > >>> >> are
>>>> >> >> > > > >>> >> > > > > further
>>>> >> >> > > > >>> >> > > > > > > downstream that don't have access to
>>>> MyFunc.
>>>> >> If
>>>> >> >> I'm
>>>> >> >> > > > >>> >> understanding
>>>> >> >> > > > >>> >> > > > > > > correctly, your proposal would work for
>>>> the
>>>> >> >> former
>>>> >> >> > but
>>>> >> >> > > > >>> not the
>>>> >> >> > > > >>> >> > > > latter.
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > > An example would be to put a configured
>>>> Logger
>>>> >> >> into
>>>> >> >> > > the
>>>> >> >> > > > >>> >> context
>>>> >> >> > > > >>> >> > > via a
>>>> >> >> > > > >>> >> > > > > > > WithLogger method (logging package -
>>>> >> >> > > > >>> knative.dev/pkg/logging
>>>> >> >> > > > >>> >> -
>>>> >> >> > > > >>> >> > > > > > pkg.go.dev
>>>> >> >> > > > >>> >> > > > > > > <
>>>> >> >> > > https://pkg.go.dev/knative.dev/pkg/logging#WithLogger
>>>> >> >> > > > >)
>>>> >> >> > > > >>> and
>>>> >> >> > > > >>> >> > then
>>>> >> >> > > > >>> >> > > > pull
>>>> >> >> > > > >>> >> > > > > > it
>>>> >> >> > > > >>> >> > > > > > > out downstream via FromContext (logging
>>>> >> package -
>>>> >> >> > > > >>> >> > > > > > knative.dev/pkg/logging
>>>> >> >> > > > >>> >> > > > > > > - pkg.go.dev <
>>>> >> >> > > > >>> >> > >
>>>> >> https://pkg.go.dev/knative.dev/pkg/logging#FromContext
>>>> >> >> > > > >>> >> > > > > >).
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > > On Wed, Feb 16, 2022 at 5:50 PM Seth
>>>> Wiesman <
>>>> >> >> > > > >>> >> > sjwies...@gmail.com>
>>>> >> >> > > > >>> >> > > > > > wrote:
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > > >> Hi Galen,
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> No, that is not currently supported, the
>>>> >> current
>>>> >> >> > > > >>> idiomatic
>>>> >> >> > > > >>> >> way
>>>> >> >> > > > >>> >> > > would
>>>> >> >> > > > >>> >> > > > > be
>>>> >> >> > > > >>> >> > > > > > to
>>>> >> >> > > > >>> >> > > > > > >> pass those values to the struct
>>>> implementing
>>>> >> the
>>>> >> >> > > > Statefun
>>>> >> >> > > > >>> >> > > interface.
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> type MyFunc struct { someRuntimeInfo
>>>> string }
>>>> >> >> func
>>>> >> >> > (m
>>>> >> >> > > > >>> >> *MyFunc)
>>>> >> >> > > > >>> >> > > > > > Invoke(ctx
>>>> >> >> > > > >>> >> > > > > > >> statefun.Context, message
>>>> statefun.Message)
>>>> >> >> error
>>>> >> >> > { }
>>>> >> >> > > > >>> func
>>>> >> >> > > > >>> >> > main()
>>>> >> >> > > > >>> >> > > {
>>>> >> >> > > > >>> >> > > > > > >> builder
>>>> >> >> > > > >>> >> > > > > > >> := statefun.StatefulFunctionsBuilder()
>>>> >> >> > > > >>> >> > > > > > >> f := MyFunc { someRuntimeInfo:
>>>> >> >> "runtime-provided" }
>>>> >> >> > > > >>> >> > > builder.WithSpec
>>>> >> >> > > > >>> >> > > > > > >> (statefun.StatefulFunctionSpec{
>>>> FunctionType:
>>>> >> >> > > > >>> >> > > statefun.TypeNameFrom(
>>>> >> >> > > > >>> >> > > > > > >> "example/my-func"), Function: f })
>>>> >> >> > > > >>> >> > > > > > >> http.Handle("/statefun",
>>>> builder.AsHandler())
>>>> >> >> > > > >>> >> > > > > > >> _ = http.ListenAndServe(":8000", nil) }
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> Would this work for you? Or what is the
>>>> >> context
>>>> >> >> > (pun
>>>> >> >> > > > >>> >> intended)
>>>> >> >> > > > >>> >> > you
>>>> >> >> > > > >>> >> > > > are
>>>> >> >> > > > >>> >> > > > > > >> looking for?
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> Seth
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> On Wed, Feb 16, 2022 at 4:35 PM Galen
>>>> Warren
>>>> >> <
>>>> >> >> > > > >>> >> > > > ga...@cvillewarrens.com
>>>> >> >> > > > >>> >> > > > > >
>>>> >> >> > > > >>> >> > > > > > >> wrote:
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >> > When stateful functions are invoked,
>>>> they
>>>> >> are
>>>> >> >> > > passed
>>>> >> >> > > > an
>>>> >> >> > > > >>> >> > instance
>>>> >> >> > > > >>> >> > > > of
>>>> >> >> > > > >>> >> > > > > > >> > statefun.Context, which wraps the
>>>> >> >> context.Context
>>>> >> >> > > > >>> received
>>>> >> >> > > > >>> >> by
>>>> >> >> > > > >>> >> > > the
>>>> >> >> > > > >>> >> > > > > HTTP
>>>> >> >> > > > >>> >> > > > > > >> > request. Is there any way to
>>>> customize that
>>>> >> >> > > > >>> context.Context
>>>> >> >> > > > >>> >> > to,
>>>> >> >> > > > >>> >> > > > say,
>>>> >> >> > > > >>> >> > > > > > >> hold
>>>> >> >> > > > >>> >> > > > > > >> > custom values, using ctx.WithValue()?
>>>> I
>>>> >> don't
>>>> >> >> > see a
>>>> >> >> > > > way
>>>> >> >> > > > >>> >> but I
>>>> >> >> > > > >>> >> > > > wanted
>>>> >> >> > > > >>> >> > > > > > to
>>>> >> >> > > > >>> >> > > > > > >> > ask.
>>>> >> >> > > > >>> >> > > > > > >> >
>>>> >> >> > > > >>> >> > > > > > >> > If not, would you be interested in a
>>>> PR to
>>>> >> add
>>>> >> >> > this
>>>> >> >> > > > >>> >> > > > functionality? A
>>>> >> >> > > > >>> >> > > > > > >> simple
>>>> >> >> > > > >>> >> > > > > > >> > way might be to add a property to
>>>> >> >> > > > StatefulFunctionSpec,
>>>> >> >> > > > >>> >> say:
>>>> >> >> > > > >>> >> > > > > > >> >
>>>> >> >> > > > >>> >> > > > > > >> > TransformContext func(ctx
>>>> context.Context)
>>>> >> >> > > > >>> context.Context
>>>> >> >> > > > >>> >> > > > > > >> >
>>>> >> >> > > > >>> >> > > > > > >> > ... that, if supplied, would be
>>>> called to
>>>> >> >> create
>>>> >> >> > a
>>>> >> >> > > > >>> >> customized
>>>> >> >> > > > >>> >> > > > > context
>>>> >> >> > > > >>> >> > > > > > >> that
>>>> >> >> > > > >>> >> > > > > > >> > would be used downstream?
>>>> >> >> > > > >>> >> > > > > > >> >
>>>> >> >> > > > >>> >> > > > > > >> > Thanks.
>>>> >> >> > > > >>> >> > > > > > >> >
>>>> >> >> > > > >>> >> > > > > > >>
>>>> >> >> > > > >>> >> > > > > > >
>>>> >> >> > > > >>> >> > > > > >
>>>> >> >> > > > >>> >> > > > >
>>>> >> >> > > > >>> >> > > >
>>>> >> >> > > > >>> >> > >
>>>> >> >> > > > >>> >> >
>>>> >> >> > > > >>> >>
>>>> >> >> > > > >>> >
>>>> >> >> > > > >>>
>>>> >> >> > > > >>
>>>> >> >> > > >
>>>> >> >> > >
>>>> >> >> >
>>>> >> >>
>>>> >> >
>>>> >>
>>>> >
>>>>
>>>

Reply via email to