panic icon indicating copy to clipboard operation
panic copied to clipboard

Implement Strategy Pattern for the ChainlinkContractStore

Open dillu24 opened this issue 3 years ago • 1 comments

Technical Story

When receiving an alert from the Alerter the AlertStore performs the following:

  • It stores the alert in Mongo
  • Stores the state of the alerted metric inside Redis. This is then used by the API/UI to display the problems in the Overview Dashboard.

Following the SRP (single responsibility principle) the AlertStore should perform one job only, that being of storing the alert in Mongo. Therefore, we need to create another component which continuously checks the values of each metric and compares them to the alertable thresholds/conditions.

In order to do this change we need to perform the following tasks:

  • Remove metric state storing logic from the AlertStore
  • Remove internal alerts mechanism as it would no longer be needed
  • Develop the MetricsStateStore by integrating each monitorable in a granular way using the Strategy pattern

Description

The aim of this ticket is to implement the Strategy Pattern for storing the Chainlink contracts' metric state. By using the Strategy Pattern we would be able to easily switch between storing strategies in the MetricStore, depending on what type of transformed data we are receiving

Resources:

  • https://refactoring.guru/design-patterns/strategy/python/example
  • https://auth0.com/blog/strategy-design-pattern-in-python/

Requirements

To achieve the aims of this ticket you need to implement a strategy that encapsulates the storing of Chainlink contract metrics. The following code snippet can be used as an example:

class MetricStateStorer:
    """
    This is the Context class,  it defines the interface of interest to clients.
    """

    def __init__(self, strategy: MetricStateStoringStrategy) -> None:
        """
        Usually, the Context accepts a strategy through the constructor, but
        also provides a setter to change it at runtime.
        """

        self._strategy = strategy

    @property
    def strategy(self) -> MetricStateStoringStrategy:
        """
        The Context maintains a reference to one of the Strategy objects. The
        Context does not know the concrete class of a strategy. It should work
        with all strategies via the Strategy interface.
        """

        return self._strategy

    @strategy.setter
    def strategy(self, strategy: MetricStateStoringStrategy) -> None:
        """
        Usually, the Context allows replacing a Strategy object at runtime.
        """

        self._strategy = strategy

    def store(self, transformed_data: TransformedData, alerts_config: AlertsConfigs) -> None:
        """
        The Context delegates some work to the Strategy object instead of
        implementing multiple versions of the algorithm on its own.
        """
        
        self._strategy.store(transformed_data, alerts_config)

class MetricStateStoringStrategy(ABC):
    """
    The Strategy interface declares operations common to all supported versions
    of some algorithm.

    The Context uses this interface to call the algorithm defined by Concrete
    Strategies.
    """

   @abstractmethod
    def store(self,  transformed_data: TransformedData, alerts_config: AlertsConfigs) -> None:
        pass

class ChainlinkContractMetricStateStoringStrategy(MetricStateStoringStrategy):
    def __init__():
        redis = Redis('localhost')

    def store(self, transformed_data: ChainlinkContractTransformedData, alerts_config: ChainlinkContractAlertsConfigs) -> None:
        chainlink_contract_metric_state_storing_helper(transformed_data, alerts_config, redis)

Acceptance criteria

Scenario: The ChainlinkContractStore storing procedure should satisfy the Strategy pattern

dillu24 avatar Jun 08 '22 09:06 dillu24

Another option is to implement the Strategy Pattern on the Existing ChainlinkContractStore and implement two abstract algorithms for the context class, store_metric_state and store_metric_value

dillu24 avatar Jun 08 '22 09:06 dillu24