-
Notifications
You must be signed in to change notification settings - Fork 10
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
Plat stop breakpoints causing timeouts #41
Conversation
…c out of the InvocationCommand and into the base class
…Value causes an overflow. - Added an extra ctor to the InvocationCommand
…d timeouts from the CommandAttribute - Added a new set of tests for the non-obsolete CommandAttribute. Put in some tests for ignoredTimeouts
|
||
// See Mjolnir's Command constructors. | ||
public CommandAttribute(string group, string isolationKey, int timeout = DefaultTimeout) : this(group, isolationKey, isolationKey, timeout) { } | ||
|
||
public CommandAttribute(string group, string isolationKey, bool ignoreTimeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this extra constructor to allow for setting specific Command calls to ignore timeouts. Is this wise? Do we want to expose this feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we do - ignoring timeouts seems like a conditional thing, so to have it baked into the attribute permanently feels odd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be honest, part of the reason for me doing this was to make testing a little bit easier. But I can take it out and just use an injected ConfigurationProvider, as is done in the current set of tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that's the way to go - it'll more align the tests with how the library is supposed to behave (i.e. driven by the config value). If we have to go this route, I think we'd want this constructor to be internal
so that it's not part of the public API.
…orking some of the code to adjust for that. Tests are broken at this time and need some rework.
… order of test matters to their success
|
||
namespace Hudl.Mjolnir.Tests.Command.Attribute | ||
{ | ||
public sealed class NewCommandAttributeAndProxyTestsIgnoringTimeouts : TestFixtureIgnoreTimeouts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TestFixtureIgnoreTimeouts
caught me here - I was reading through the tests and said to myself, "it looks like these aren't actually using the ignoreTimeouts
property", and I stumbled upon how it was used later. What are your thoughts on bringing the config value closer to the tests here? It feels too disconnected to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that, just means running the TestFixtureIgnoreTimeouts and TestFixture constructor logic at the start of each test.
A lot of changes but In the spirit of the xunit philosophy maybe we should do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robhruska Having started to move this logic to the start of each of the ~160 tests, I'm starting to think it's better where it is in the constructor. Here's my reason;
In each test, since we don't know what other tests may have done to the ConfigProvider, we have to initialise all of the possible keys. e.g. in a test where we're not looking to test anything related to the ignoreTimeouts functionality we still need to start the test off with a
ConfigProviderContext.Instance.SetConfigValue(ConfigProviderContext.IgnoreTimeoutsKey, false);
This seems like code bloat, and is perhaps more confusing than having it all in one place?
It also makes it tricky if we end up adding another config value to the tests!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In each test, since we don't know what other tests may have done to the ConfigProvider
If we assume that other tests appropriately tore themselves down, is that enough?
we still need to start the test off with a ...
If we can assume a sane config state, and the config value defaults to false
, we should only have to add it to cases where we want to set it with a true
value.
Thoughts there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that relying on assumptions in a unit test for it to pass, is a little bit flawed. Also if one test forgets to tear down properly then finding where that is could be more tricky.
But on the other hand if we actually changed the default values for config inside of mjolnir in the future, then I would hope a bunch of failing tests would be enough for someone to reconsider what they're doing. This is probably the biggest benefit so I'll go with the approach of just setting values where they are needed and assuming that the world is otherwise configured using defaults.
_log.DebugFormat("Timeout configuration override for this command of {0}",timeout); | ||
//I think it is sensible to apply this timeout to the command if it has been explicitly set in configuration. | ||
//Therefore setting TimeoutsFullyDisabled to false regardless | ||
TimeoutsIgnored = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels a little hidden to me. As a user of the library, if I set mjolnir.ignoreTimeouts=True
, that feels like a pretty assertive thing (like, I expect it to ignore all timeouts). If I were to set the config to True and still encounter a timeout, I'd be confused. Additionally, in local development, I'm almost positive that we have 0 people with per-command timeouts configured, so I'm not sure there's much of a problem to address by doing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess ignoreTimeouts should be fully self explanatory. I was in two minds as to what I was going to do with these per command timeouts. My thought was that it may give users the ability to apply the blanket ignore first, then if they were interested in tweaking the timeout for a particular command they could just work with the per-command config.
I guess since the per-command config overrides the default anyway you can still get the same use case.
I'll change it.
…at the default ConfigurationValues apply.
@@ -169,7 +177,8 @@ internal Command(string group, string name, string breakerKey, string poolKey, T | |||
throw new ArgumentNullException("poolKey"); | |||
} | |||
|
|||
if (defaultTimeout.TotalMilliseconds <= 0) | |||
TimeoutsIgnored = IgnoreCommandTimeouts.Value; | |||
if (!TimeoutsIgnored && defaultTimeout.TotalMilliseconds <= 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically I don't think we need to check the ignored flag here - the default timeout's often going to get passed from a constant or hard-coded value, so it should be valid.
In fact, thinking about it more, I'd lobby to always validate the default timeout here, because otherwise, if timeouts are ignored, invalid default timeout values might go unnoticed in development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true! I think there's actually a test which looks at this. It will give a false positive in the case where ignoredTimeouts is true and the timeout is <=0
- cleaning up some overly verbose code
/// This is likely to be useful when debugging Command decorated methods, however it is not advisable to use in a production environment since it disables | ||
/// some of Mjolnir's key features. | ||
/// </summary> | ||
protected static readonly ConfigurableValue<bool> IgnoreCommandTimeouts = new ConfigurableValue<bool>("mjolnir.ignoreTimeouts", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with Mjolnir being open source are we ok referencing ConfigurableValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we've got a version of Hudl.Config
that's published to nuget.org
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't made any changes to mjolnir's references
Plat stop breakpoints causing timeouts.
Commands now have the facility to ignore the timeouts. This should make it easier to debug Command decorated methods.
Ignoring timeouts can either be configured using the CommandAttribute constructor (in Hudl.Mjonir.Attributes), or using a ConfigurableValue (for system wide ignoring of timeouts).