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

Outbox cleanup circuit breaker #242

Merged
merged 3 commits into from
Dec 1, 2016
Merged

Conversation

ramonsmits
Copy link
Member

Quick draft to resolve #241

I have put the circuit breaker creation in the cleaner as that already contains configuration. In core circuitbreakers are created in the feature which seems to make more sense but that felt strange to do here unless that configuration value retrieval code is moved to the feature too.

@MarcinHoppe MarcinHoppe changed the title WIP: Outboxcleaner circuitbreaker [WIP] Outboxcleaner circuitbreaker Nov 17, 2016
…e and used it in OutboxCleaner as that also does other initialization.
@MarcinHoppe MarcinHoppe force-pushed the outboxcleaner-circuitbreaker branch from d771deb to 1987bc2 Compare November 24, 2016 08:38
@MarcinHoppe
Copy link
Contributor

I rebased this PR on top of develop.

@MarcinHoppe
Copy link
Contributor

@ramonsmits @Particular/nhibernate-persistence-maintainers Can we use the value that is set using TimeToWaitBeforeTriggeringCriticalErrorOnTimeoutOutages? See doco here:

https://docs.particular.net/nservicebus/recoverability/critical-exception-for-timeout-outages

It also applies to the persister, so it would make sense to have the circuit breaker behave in the same way for the Timeouts and well as the Outbox.

@MarcinHoppe
Copy link
Contributor

We could rename the method to not include the Timeouts part in core 6.1 (obsolete with a warning).

@MarcinHoppe
Copy link
Contributor

@ramonsmits @Particular/nhibernate-persistence-maintainers I think this PR is good to go, assuming that we want to configure the circuit breaker via AppSettings.

Please chime in here.

@MarcinHoppe MarcinHoppe changed the title [WIP] Outboxcleaner circuitbreaker Outbox cleanup circuit breaker Nov 24, 2016
@ramonsmits
Copy link
Member Author

ramonsmits commented Nov 25, 2016

Can we use the value that is set using TimeToWaitBeforeTriggeringCriticalErrorOnTimeoutOutages

@MarcinHoppe I intentionally didn't as these are two independent features that would then share implicit schema. Also, the timeout storage is only applicable if the transport doesn't support timeouts natively.

@MarcinHoppe
Copy link
Contributor

Also, timeouts and Oubox can use two different persisters, so it wouldn't always be good to share the circuit breaker timeout. I think the current API (AppConfig) is good enough and consistent with other Outbox configuration parameters.

@MarcinHoppe
Copy link
Contributor

@SzymonPobiega @HEskandari Can you give this PR a look and merge?

@@ -36,6 +37,25 @@ protected override Task OnStart(IMessageSession busSession)
throw new Exception("Invalid value in \"NServiceBus/Outbox/NHibernate/FrequencyToRunDeduplicationDataCleanup\" AppSetting. Please ensure it is a TimeSpan.");
}

var key = "NServiceBus/Outbox/NHibernate/TimeToWaitBeforeTriggeringCriticalErrorWhenCleanupTaskFails";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually inlined this variable to be consistent with how other configuration keys are handled. Key values seem to be descriptive and only used locally in this file. Since they don't change often (doco), encapsulating them brings little value.

Agree?


if (configValue == null)
{
timeToWaitBeforeTriggeringCriticalError = TimeSpan.FromMinutes(2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract TimeSpan.FromMinutes(2) as a readonly field to give it more visibility?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted this and all the other TimeSpans in this file into separate static readonly fields.

@SzymonPobiega
Copy link
Member

Few minor things. Otherwise LGTM.

@SzymonPobiega
Copy link
Member

@ramonsmits @MarcinHoppe ping.

Copy link
Contributor

@HEskandari HEskandari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. Here's my review.

return;
}

timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit hard to read and capture the intent. Would it be a good idea to have a properly named/intent capturing private method? This is subjective of course so feel free to ignore if you disagree.


if (newValue == 1)
{
timer.Change(timeToWaitBeforeTriggering, NoPeriodicTriggering);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the above.

TimeSpan timeToWaitBeforeTriggering;
Action<Exception> triggerAction;

static TimeSpan NoPeriodicTriggering = TimeSpan.FromMilliseconds(-1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this the same as Timeout.Infinite?

}

long failureCount;
Exception lastException;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the last exception enough? or should we go with an AggregateException instead? That'd require a bit more code to ensure exceptions are aggregated correctly and cleared when successful.

Inline config key names
@MarcinHoppe
Copy link
Contributor

@HEskandari The circuit breaker code has been copied verbatim from the core. Do we want to impove upon the code and risk these two copies getting out of sync?

I'd rather do a PR in the core and then copy what they come up with. Thoughts?

@HEskandari
Copy link
Contributor

@MarcinHoppe fair enough.

@MarcinHoppe
Copy link
Contributor

@HEskandari OK. Can I dismiss your request for changes?

@SzymonPobiega If you are OK with my latest changes, this is ready for merge (build is green).

@SzymonPobiega SzymonPobiega merged commit babe34d into develop Dec 1, 2016
@SzymonPobiega SzymonPobiega deleted the outboxcleaner-circuitbreaker branch December 1, 2016 09:17
@SzymonPobiega
Copy link
Member

@MarcinHoppe done.

SzymonPobiega added a commit that referenced this pull request Dec 5, 2016
* Imported RepeatedFailuresOverTimeCircuitBreaker, removed unneeded code and used it in OutboxCleaner as that also does other initialization.

* Simplify critical error message

* Format code

* Extract time parametes into constants
SzymonPobiega added a commit that referenced this pull request Dec 9, 2016
* Imported RepeatedFailuresOverTimeCircuitBreaker, removed unneeded code and used it in OutboxCleaner as that also does other initialization.

* Simplify critical error message

* Format code

* Extract time parametes into constants
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants