Skip to content

Version 2 To 3 Upgrade

Damian Turczyński edited this page Feb 7, 2018 · 9 revisions

Upgrade from version 2 to version 3

There are some breaking changes with version 3. This is a guide which should help you migrate. For more specific details on the changes, you can view the version 3.0.0 PR here

.NET Core support

In order to make Mjolnir compatible with .NET Core we're now targeting netstandard1.6, meaning the library is now only compatible with .NET Core application at v1.0.0 or above and with the .NET framework v4.6.1 or above.

IStats removal

The IStats interface and implementations are removed. The preferred replacement is IMetricEvents which has the same functionality.

Configuration upgrade

The dependency on the Hudl.Config nuget package has been removed, to help with encapsulation and dependency resolution.

Version 3.0.0 of Mjolnir introduces strongly typed config, replacing the string-key based config from v2.*. New config is represented by MjolnirConfiguration class.

In order to configure Mjolnir you're required to pass an instance of the MjolnirConfiguration class with all configuration values attached to the appropriate properties of the class. We have provided a sample implementation which will read configuration from a JSON file and reloads configuration when there have been any changes to that file. See ExampleJsonConfigProvider.

For more information about meaning of the configuration go to Configuration, and for more information on setting up the CommandInvoker with configuration see Installing-and-Configuring

Mapping

Below we provide mapping from old configuration key to new configuration attributes:

Global keys

mjolnir.isEnabled -> MjolnirConfiguration.IsEnabled
mjolnir.ignoreTimeouts -> MjolnirConfiguration.IgnoreTimeouts
mjolnir.useCircuitBreakers -> MjolnirConfiguration.UseCircuitBreakers

Command Timeouts

// Fallback default command timeout (A new key)
MjolnirConfiguration.DefaultCommandConfiguration.Timeout

// configured command timeouts
command.<command-name>.Timeout -> MjolnirConfiguration.CommandConfigurations[<command-name>].Timeout 

Bulkheads

// Default concurrency level
mjolnir.bulkhead.default.maxConcurrent -> MjolnirConfiguration.DefaultBulkheadConfiguration.MaxConcurrent

// overrides for named keys
mjolnir.bulkhead.<bulkhead-key>.maxConcurrent -> MjolnirConfiguration.BulkheadConfigurations[<bulkhead-key>].MaxConcurrent

Circuit Breakers

// Defaults
mjolnir.breaker.default.minimumOperations -> MjolnirConfiguration.DefaultBreakerConfiguration.MinimumOperations
mjolnir.breaker.default.thresholdPercentage -> MjolnirConfiguration.DefaultBreakerConfiguration.ThresholdPercentage
mjolnir.breaker.default.trippedDurationMillis -> MjolnirConfiguration.DefaultBreakerConfiguration.TrippedDurationMillis
mjolnir.breaker.default.forceTripped -> MjolnirConfiguration.DefaultBreakerConfiguration.ForceTripped
mjolnir.breaker.default.forceFixed -> MjolnirConfiguration.DefaultBreakerConfiguration.ForceFixed

// Overrides for named breakers
mjolnir.breaker.<breaker-key>.minimumOperations -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].MinimumOperations
mjolnir.breaker.<breaker-key>.thresholdPercentage -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].ThresholdPercentage
mjolnir.breaker.<breaker-key>.trippedDurationMillis -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].TrippedDurationMillis
 
mjolnir.breaker.<breaker-key>.forceTripped -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].ForceTripped
mjolnir.breaker.<breaker-key>.forceFixed -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].ForceFixed

Metrics

Metrics configuration has moved to breaker configuration with the following

mjolnir.metrics.default.windowMillis -> MjolnirConfiguration.DefaultBreakerConfiguration.WindowMillis
mjolnir.metrics.<breaker-key>.windowMillis -> MjolnirConfiguration.BreakerConfigurations[<breaker-key>].WindowMillis

New Keys

// Configures the time window to use for assessing breaker metrics over. 
MjolnirConfiguration.BreakerConfigurations[<breaker-key>].SnapshotTtlMillis

Removed keys

Removed ability to configure gauge intervals for metric events. Gauges now fire at a fixed 1000 ms interval; it a client is implementing IMetricEvents and handling gauge calls, the client should handle debouncing or otherwise aggregating the gauges at a less frequent resolution if desired.

mjolnir.bulkheadConfigGaugeIntervalMillis -> N/A (feature no longer available in version 3.0)
mjolnir.breakerConfigGaugeIntervalMillis -> N/A (feature no longer available in version 3.0)

Configuration updates

Mjolnir supports dynamic configuration updates, meaning the library will respond to changes in the properties of the MjolnirConfiguration object you passed in when configuring the CommandInvoker. However after any property changes you are required to call the MjolnirConfiguration.NotifyAfterConfigUpdate() method to notify the library of the changes.

CommandInvoker creation

The static CommandInvoker.Instance has been removed. We still recommend using a single instance of the CommandInvoker throughout your application and also recommend the use of Dependency Injection mechanisms to create and manage a singleton ICommandInvoker throughout an application.

Callers who need static access should consider creating a static singleton wrapper around a single instance of CommandInvoker.

Commands

The Command class has been removed in favour of implementing async and sync commands with the seperate base classes, SyncCommand and AsyncCommand.

Logging

In Mjolnir 3.0.0 we're removing the hard dependency on log4net, and instead using logging interfaces, giving users of the library the chance to wire up the logging to their preferred implementation. The default implementation in the Mjolnir library is a no-op logger (see DefaultMjolnirLog and DefaultMjolnirLogFactory). Since the primary entry point to the Mjolnir library will be the CommandInvoker, you can pass in your own implementation of the IMjolnirLogFactory here.

Hudl.Mjolnir.Attributes

Removed Hudl.Mjolnir.Attributes and the reflective proxying helper classes. Clients can re-implement these if desired, but this 1) removes a dependency on Castle.Core, and 2) though convenient, fosters a pattern (using attributes) that makes code hard to unit test. We may bring this back in the future if it's needed, but if we do it'll be as a separate library instead of built into Mjolnir proper.

Exceptions

The following Command* exceptions have been removed:

  • Hudl.Mjolnir.Command CommandCancelledException
  • Hudl.Mjolnir.Command CommandFailedException
  • Hudl.Mjolnir.Command CommandRejectedException
  • Hudl.Mjolnir.Command CommandTimeoutException

Where in version 2.6.* these exceptions were thrown by calls through the CommandInvoker, in v3.0.0 there are only 4 types of exception that could be thrown.

  1. A custom exception that is throw by your own implementation of (Async/Sync)Command
  2. OperationCanceledException, which will be thrown for a timeout or cancellation of a command.
  3. CircuitBreakerRejectedException, thrown when the command circuit breaker has been tripped.
  4. BulkheadRejectedException, thrown when the command's bulkhead is overloaded with too many concurrent calls.