profile
viewpoint

timothybasanov/terminal-app-function-keys 12

Terminal.app configuration handling Fn keys right

timothybasanov/steamkeysactivator 11

Activates a bulk of Steam keys on Mac OS X

timothybasanov/homebrew-google-authenticator 3

Google Authenticator homebrew tap

timothybasanov/homebrew-xpra 1

Homebrew tap for Xpra

timothybasanov/zeroshell-linode 1

Script for Zeroshell installation on Linode (Xen)

timothybasanov/eap_proxy 0

Proxy EAP packets between interfaces on a Ubiquiti Networks EdgeRouter™ Lite

timothybasanov/guiceberry 0

Leverage Guice to achieve Dependency Injection on your JUnit tests

timothybasanov/homebrew-cask 0

A CLI workflow for the administration of Mac applications distributed as binaries

timothybasanov/homebrew-core 0

:beers: Core formulae for the Homebrew package manager

timothybasanov/homebridge-camera-ffmpeg-ufv 0

UniFi Video plugin for Homebridge

issue openedfailsafe-lib/failsafe

Regression: Failsafe 2.4.x getStageAsync may hang

Something has changed after 2.4.2. A combination of Timeout and RetryPolicy with getStageAsync() makes Failsafe to hang sometimes. Here is an example that's reproducible on a 2.4.x, but not on a master branch:

Timeout<Integer> timeout = Timeout.of(Duration.ofMillis(100));
RetryPolicy<Integer> retryPolicy = new RetryPolicy<Integer>()
        .withBackoff(10, 30, ChronoUnit.MILLIS)
        .withMaxRetries(2);
var result = Failsafe.with(retryPolicy, timeout).getStageAsync(() -> CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(500);
                return 1;
            } catch (InterruptedException e) {
                throw new RuntimeException("Interrupted");
            }
        }));
System.out.println("Result=" + result.join()); // Hangs here

It would be nice to have a fix on 2.4.x branch for people that find it may be hard to migrate to 2.5.x for some time.

created time in a month

issue commentfailsafe-lib/failsafe

Make some internal APIs more open

Not a Contribution.

Timeout only has a private constructor, so I can't extend it So you'd prefer a protected constructor? Are you using Timeout with the existing TImeoutExecutor or with your own? For 3.0 I'm actually planning to have private constructors on all policies and to let them be built via a Builder, FWIW, as part of #47.

Yes, protected constructors for all policies would be appreciated. I often want to tweak only one aspect of the policy by extending it (e.g. getTimeout() using a lambda). If it's fully locked up, I'll have to create a copy-and-paste of the whole class for even minor modifications.

You mean something like Consumer<Duration> timeout, or something else? Maybe you can describe the use case? ... I'm curious though what kind of jitter changes you're making.

Yep, ideally a Function<SomeContext, Duration> for a timeout to have different timeouts for different retries, and a delay between retries to allow to use a pre-existing custom jitter function. For all my policies I have to be able to change all their parameters at runtime, so I prefer to have lambdas everywhere. Usually I add additional methods/constructors in a child class with lambdas instead of values and try to integrate them by auto-calling original setters when a lambda value changes.

Of course we could make it easy to create a new copy. Would that work for you?

Yep, if I can freely convert from policy to its builder and back, it would solve some of my issues. I would be able to store a "master copy" of a policy, and create "adjusted" ones when necessary for special cases. As an example different methods called on the same RPC service have very similar, but still slightly different configuration.

transitionTo could be made protected, but couldn't you still call super.close() to cause the transition? I'm not sure what you mean re: onClose and a list. I want to replace an onClose lambda with a list of lambdas to be able to add as many listeners as I want. The easiest way is to add a list of listeners as a field in a class and work with it instead of the original onClose. This requires a custom implementation of onClose.

Can't replace TimeoutExeededException with a subclass This might be better as a top ievel feature - same for CircuitBreakers. Does #225 sound right for that? Yep, you're right, it could be done with a Fallback policy without any changes to API.

These were only a few random examples. In general, I would recommend against locking up a framework with package locals or privates unless there is absolute certainty that end user would not want to reuse or adjust this functionality.

timothybasanov

comment created time in 2 months

issue openedfailsafe-lib/failsafe

Support backup requests

Not a Contribution.

As mentioned in #159 and #291 there is an additional layer on top of hedged/staggered retries that we may need to support: a backup requests. In short, backup requests are similar to fallbacks, but done async

What's the difference with hedged retries? What features are required?

  • Backup requests are issued immediately and in parallel to the main request
  • Backup request results are not used unless the main request and its retries fail
  • We do not need to support fallbacks for a main request if a backup request is present

Ideally backup requests should support a separate retry policy and circuit breakers. Both are needed for real world requests over the network. But even if retries/circuit breakers are not supported for a backup policy, a workaround would be to implement them as a separate Failsafe executor that is only used within a Fallback policy as an implementation detail.

One of the ways to achieve this in terms of API would be to extend an existing Fallback policy to allow its execution to start in parallel to the main request.

created time in 2 months

issue commentfailsafe-lib/failsafe

Support staggered/hedged/backup retries

Not a Contribution.

To better align with #159, mentioning hedged requests as they are seemingly are a different name/flavor for staggered requests.

timothybasanov

comment created time in 2 months

issue commentfailsafe-lib/failsafe

[DISCUSS] Failsafe Roadmap

Not a Contribution.

Not sure if I understand backup requests correctly, so I'm describing a behaviour that would be nice to have in my case:

Backup request is a bit different from a hedged one. It's more similar to an existing Fallback policy, but it starts its execution immediately, in parallel to the main request. Its results are only used when the main request fails. It may also need some retries/circuit breakers/fallbacks configured.

jhalterman

comment created time in 2 months

issue commentfailsafe-lib/failsafe

Make some internal APIs more open

Not a Contribution

As an exercise I've tried to create a few custom policies. A few things that spring to my attention:

  • Timeout only has a private constructor, so I can't extend it
  • Replacing timeout's Duration with a lambda is hard. I have to pass null to a constructor as a workaround
  • I can't create custom logic by subclassing TimeoutExecutor, it's package-private
  • It's hard to make a RetryPolicy's duration mutable. I have to override all methods and guard them with locks to make it thread safe
  • I can't replace jitter generation logic with a different one as RetryPolicyExecutor#adjustForJitter is private
  • CircuitBreaker uses state.get() instead of getState(), and currentExecutions are private. This makes it impossible to have a custom recordSuccess()
  • CircuitBreaker does not allow to replace onClose with a list. If I override close() I can't call a private transitionTo()
  • Can't replace TimeoutExeededException with a subclass (with additional details e.g. duration). Most natural place is to replace PolicyExecutor#execution with a custom one, but AbstractExecution has a package-local constructor, on top of that it's not clear how can I wrap/intercept a call to Timeout#toExecutor which is done from places like ExecutionImpl which are also package-private

This is still a significant improvement over 2.4. I can now copy-paste the whole Timeout and its TimeoutExecutor to adjust the way I need it.

timothybasanov

comment created time in 2 months

issue commentfailsafe-lib/failsafe

Considering allowing a Future result to be completed immediately when a Timeout occurs

Not a Contribution.

Cancellation examples:

  • Interrupted RPC call throws a custom exception that contains detailed information about the operation being done (e.g. resolution of a host within an SRV/TXT record), and an RPC context (e.g. unique request ID set in an interceptor)
  • Report a metric (again using an internal RPC request-specific information)
  • Cancel other request-related tasks/futures running in other thread pools or NIO resources (workarounds for an underlying RPC framework's issues)

Fallbacks can't really be used. Some example details that only the underlying RPC framework may know during an execution: "Tried to resolve a hostname that we got dynamically", "RPC context contained this metadata set in an interceptor". In practice, in a place where I configure a failsafe retry I only have a lambda to call so I don't have access to any context.

Yep, that's exactly what I'm thinking!

jhalterman

comment created time in 2 months

more