...
Since we’ve decided to go with Option 2 and Option 4, and to implement a circuit breaker pattern, the main focus of the technical delivery will be on how to integrate this into the mod_scheduler
service and what approaches we should use. For the future, we have also decided to create a dashboard that can display timers along with their statuses. To achieve this, we will introduce timer statuses in the first iteration of implementation, which the UI will then use to display them on the dashboard.
Own imllementation
Firstly, I think we don't need to introduce a new framework to handle the circuit breaker pattern; we should try to implement it using the existing Quartz framework. Since Quartz is already established for the service and supports distributed job handling, the idea is to pause the timer job each time it fails and create a circuit breaker job, which will be scheduled to execute based on the number of timer failures. We will store the number of failures for the timer job in the timer descriptor, along with the timer statuses.
Hystrix
The most popular circuit breaker pattern library, built by Netflix, is Hystrix. The implementation will be straightforward: we'll wrap our call to the timer endpoint with a HystrixCommand
, running asynchronously and managing all statuses if the call fails. Each HystrixCommand
should have a unique key, which should match the timer job key.
pros
popular and easy implementation
cons
"multi instances" implementation - each node has completely separate circuit breakers and there's no shared data between nodes
resilience4j
Another popular library that implements the circuit breaker pattern provides a circuit breaker registry, allowing us to register our circuit breakers. It can be customized to use not only in-memory storage but also shared services like an in-memory database or a traditional database.
Pros:
Easy to implement
The registry can be shared across instances
cons
Extend Time Descriptor to add two new properties: failed status and failure count
Code Block |
---|
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "TimerDescriptor", "description": "Timer", "type": "object", "properties": { "id": { "description": "Timer identifier", "type": "string", "format": "uuid" }, "modified": { "description": "Whether modified", "type": "boolean" }, "routingEntry": { "$ref": "routingEntry.json", "description": "Proxy routing entry" }, "enabled": { "description": "Whether enabled", "type": "boolean" }, "moduleName": { "description": "Module name timer belongs to", "type": "string" }, "lastFailedDate": { "description": "The date of the last failure.", "type": "boolean" }, "failureCount": { "description": "Failure count", "type": "integer" } }, "required": [ "routingEntry", "enabled" ] } |
Drawio | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...