Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context propagation #1115

Open
waeljammal opened this issue May 21, 2024 · 2 comments
Open

Context propagation #1115

waeljammal opened this issue May 21, 2024 · 2 comments

Comments

@waeljammal
Copy link

waeljammal commented May 21, 2024

Is your feature request related to a problem? Please describe.

we have actors calling other actors in the cluster and those actors might do things like starting a database transaction, or something else that takes a context.Context, it would be great if a future request for example that has a timeout set would propagate and make the context available to the actor like actorCtx.Context() so that it can be passed along the chain or to fail a transaction if the requestor is not going to get an error because the request timed out mid way through handling it.

Another use for this would also be for us to propagate trace info in the context when using otel so we can get better trace output. Simply passing this context to the mongo client for eg. would include the db operation in the trace, doing this any other way is resulting in a lot of boiler plate code, the send, future etc. functions should take a context.

This will also allow developers to add their own traces to those the library might generate more easily.

Also tracing does not seem to work when using cluster kinds, I registered the middleware but no traces. It looks like the placement actor ignores all middlewares when using cluster kinds.

Describe the solution you'd like
Access to a go context on the actor context, grpc already supports propagating metadata using md so it should be possible to propagate timeout, trace headers etc.

Describe alternatives you've considered
Creating a message envelope to wrap the info or middleware to replace the default actor context but this won't work because it changes the signature of the Receive function.

@ljluestc
Copy link

package main

import (
    "context"
    "fmt"
    "time"

    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/trace"
)

// Define a custom actor system
type Actor struct {
    name string
}

// Simulate actor's work with context
func (a *Actor) ProcessRequest(ctx context.Context, request string) error {
    // Start a trace for the actor's work
    tracer := otel.GetTracerProvider().Tracer("actor-system")
    _, span := tracer.Start(ctx, fmt.Sprintf("%s-processing", a.name))
    defer span.End()

    // Simulate a long-running operation, like a DB transaction
    select {
    case <-time.After(2 * time.Second):
        // Simulating successful operation
        fmt.Println(a.name, "processed:", request)
    case <-ctx.Done():
        // If the context is canceled or timed out, return the error
        fmt.Println(a.name, "timed out processing:", request)
        return ctx.Err()
    }

    return nil
}

func main() {
    // Example for creating and running the actor with context propagation
    actor := &Actor{name: "Actor1"}

    // Create a context with a timeout
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()

    // Call the actor's method with context
    err := actor.ProcessRequest(ctx, "Database Query")
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Request processed successfully")
    }
}

@chadleeshaw
Copy link

I second this. Other actor frameworks I've looked at have actor.Context.Context() that you can pass to things that require a Context argument. Its a nice to have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants