Ratpack request/execution scope in Hystrix threads

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Ratpack request/execution scope in Hystrix threads

donaldquixote
I have been scoping some of my objects to ratpack-guice's RequestScoped and ExecutionScoped scopes, but now that I am instrumenting my service with Hystrix, this approach won't work as is - the Hystrix threads are not ratpack-managed, so ratpack Executions are not available.

Has anyone else run into this or have any ideas on how to work around it? Any Hystrix isolated block configured within a request handler/chain is still a necessary component of the request, so it doesn't seem like I'm asking for anything exotic or nonsensical.

I've looked into HystrixRequestContext and related classes, but these don't seem like the appropriate tools for the job.

Thanks.
rus
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

rus
Which command type are you using?  Have you tried HystrixObservableCommand?

Are you able to provide an example we can work through?
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

donaldquixote
Only the synchronous command right now. An example in my code would boil down to what is below. My code is factored in a way where providing access to the context's registry is not practical or desirable where the injected object is needed, hence the use of javax.inject APIs.

The behavior I see is an UnmanagedThreadException coming from ExecutionBasedScope#getScopedObjectMap, when it invokes Execution#current. I have verified that moving the call to Provider#get out of the hystrix command resolves the issue.

I am on version 1.2.0 for all ratpack-related jars in my project.


/////////////////////////////////////////////////////////////////////////////////////

class MyGuiceModule implements Module {
    public void configure(Binder binder)
    {
        binder.bind(TransactionManager.class).to(CommonTransactionManager.class).in(ExecutionScoped.class);
     }
}

...

class MyHandler implements Handler
{
    @Inject
    Provider<TransactionManager> txManagerProvider;

    void handle(Context ctx)
    {
        Blocking.get(() -> {
            new HystrixCommand<Void>(options) {
                protected Void run() throws Exception {
                    txManagerProvider.get().doStuff();
                    return null;
                }
            }.execute();
        });
    }
rus
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

rus
I would try using HystrixObserbableCommand instead https://ratpack.io/manual/current/hystrix.html#which_command_execution_to_use

Otherwise you will need to pass TransactionManager into your command when you create it.
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

donaldquixote
I will certainly try, but I'm curious to understand exactly how this would resolve the issue. Under the covers, are observable hystrix commands being processed on ratpack-managed threads? Or is something else at play?
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

donaldquixote
It does seem to resolve the issue. A ratpack execution object is available now where it was not before. I'm still curious for the reasoning behind this. Why can't a blocking hystrix command be bound to an execution?
rus
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

rus
Because it is not running on a ratpack managed thread.  Those commands by default use thread pool as a strategy for throttling and so you are running on a hystrix thread.  The observable commands use the semaphore strategy and are still running on the compute thread.
 
You may be able to get HystrixCommand working as you want if you configure it to use semaphore instead of threadpool, I haven't tried this.  However, I would recommend using the observable command anyway.  It is the only non blocking command, the others would need to be wrapped in a blocking call.

Hope that makes sense.  I'm on my phone sorry.
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

donaldquixote
Makes sense. I'm still very new to Hystrix, so the different isolation/throttling strategies did not occur to me. I now wonder why the default strategies are what they are for the different Hystrix command types, but I don't want to drag this thread on too long :)

Thanks for your time!
rus
Reply | Threaded
Open this post in threaded view
|

Re: Ratpack request/execution scope in Hystrix threads

rus
It's because the observable command is designed to be used in non blocking (reactive) architectures.   The other commands in thread per request architectures