I agree with you Galen, adding a default implementation would not be so
natural here. We could eventually change this from being an interface to
just a struct (like http.Request) if there is no use case for custom
implementations.

Thanks for the nice discussion here + contribution :)

Austin


On Wed, Feb 23, 2022 at 11:09 AM Galen Warren <ga...@cvillewarrens.com>
wrote:

> Thanks, Till.
>
>
>> Is it possible in Go to provide a default implementation for a method?
>> Maybe that way the introduction of the new method would not be breaking.
>>
>
> I can't think of a way to do this that would be seamless to someone who
> had chosen to create a custom struct implementing statefun.Context. We
> could create a struct -- say, statefun.ContextDefaultBehavior -- that an
> implementor could embed in such a custom struct and which would provide an
> implementation of WithContext, but that embedding would have to be added to
> the custom struct (i.e. it wouldn't prevent the initial compile-time
> breakage), and there would be no way to provide an implementation that
> would work in the general case. I'm not sure that would be any better than
> just requiring the implementor to add a WithContext method.
>
> Austin, please chime in if you have a different idea.
>
> I'll proceed for now with the intent of adding the method to
> statefun.Context. If we decide that a top-level function is a better
> approach, that would be an easy switch to make.
>
> JIRA created: [FLINK-26340] Add ability in Golang SDK to create new
> statefun.Context from existing one, but with a new underlying
> context.Context - ASF JIRA (apache.org)
> <https://issues.apache.org/jira/browse/FLINK-26340>
>
> I have the code basically done locally, so, barring objection, I'll add a
> PR soon.
>
>
>
>
>
>
> On Wed, Feb 23, 2022 at 3:41 AM Till Rohrmann <trohrm...@apache.org>
> wrote:
>
>> Thanks a lot for the discussion Austin and Galen. I think it would be fine
>> to break the API at this point in time. Moreover, I don't assume that many
>> people have their own statefun.Context implementations. Is it possible in
>> Go to provide a default implementation for a method? Maybe that way the
>> introduction of the new method would not be breaking.
>>
>> Galen, do you want to open a JIRA issue for this proposal?
>>
>> Cheers,
>> Till
>>
>> On Wed, Feb 23, 2022 at 12:50 AM Galen Warren <ga...@cvillewarrens.com>
>> wrote:
>>
>> > Yeah, good point. I wasn't considering that someone else might be
>> > implementing that interface. Practically, I think that's pretty
>> unlikely,
>> > but good question.
>> >
>> >
>> >
>> > On Tue, Feb 22, 2022 at 6:36 PM Austin Cawley-Edwards <
>> > austin.caw...@gmail.com> wrote:
>> >
>> > > I think the only complication with adding `WithContext` to the
>> interface
>> > > is that it makes it breaking :/ If it were the concrete
>> implementation,
>> > > we'd have more flexibility. I'm not sure what guarantees are on those
>> > > interfaces though – @sjwies...@gmail.com, wdyt?
>> > >
>> > > On Tue, Feb 22, 2022 at 4:19 PM Galen Warren <ga...@cvillewarrens.com
>> >
>> > > wrote:
>> > >
>> > >> I think I would choose the WithContext method at this point, assuming
>> > >> that the implementation keeps any instance of the stateful context
>> > >> immutable (which should be doable). It's the simplest option IMO,
>> > simpler
>> > >> than an adapter approach. Thanks for the suggestion.
>> > >>
>> > >> My slight preference would be to add 'WithContext' as a method to
>> > >> statefun.Context (similar to your Request.WithContext example
>> > >> <https://pkg.go.dev/net/http#Request.WithContext>), as opposed to a
>> > >> top-level function, i.e. statefun.WithContext, but either one could
>> > work.
>> > >>
>> > >> Would that work for you? What do the rest of you think?
>> > >>
>> > >>
>> > >>
>> > >> On Tue, Feb 22, 2022 at 3:52 PM Austin Cawley-Edwards <
>> > >> austin.caw...@gmail.com> wrote:
>> > >>
>> > >>> 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