Skip to content

Commit

Permalink
write documentation for exponential retry strategy and idempotent req…
Browse files Browse the repository at this point in the history
…uest
  • Loading branch information
Eazybright committed Oct 20, 2023
1 parent 6023664 commit 3ff5d49
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,44 @@ client.delete_topic('<insert-topic-key>')
client.subscriber_topic('<insert-topic-key>', '<insert-externalSubscriberId>')
```

### Idempotent Request

This SDK allows you to perform idempotent requests, that is safely retrying requests without accidentally performing the same operation twice.
To achieve this, provide an `idempotency_key` argument during initialization of the NOVU client. We strongly recommend that you use [UUID](https://datatracker.ietf.org/doc/html/rfc4122) format when you're generating your idempotency key.

```ruby
client = Novu::Client.new(
access_token: '<your-novu-api_key>',
idempotency_key: '<your-idempotency-key>'
)
```

### Exponential Retry Mechanism

You can configure this SDK to retry failed requests. This is done by using [Exponential backoff strategy](https://en.wikipedia.org/wiki/Exponential_backoff). It is a common algorithm for retrying requests. The retries gradually extend the waiting time until reaching a specific limit. The concept is to prevent overloading the server with simultaneous requests once it is back online, especially in cases of temporary downtime.

```ruby
client = Novu::Client.new(
access_token: '<your-novu-api_key>',
idempotency_key: '<your-idempotency-key>',
enable_retry: true, # it is disabled by default,
retry_config: {
max_retries: 3,
initial_delay: 4,
max_delay: 60
}
)
```

## The retry configuration is explained in the following table:
| Options | Detail | Default Value | Data Type |
| ------------- | -------------------------------------------------------------------| --------------- | --------- |
| max_retries | Specifies total number of retries to perform in case of failure | 1 | Integer |
| initial_delay | Specifies the minimum time to wait before retrying (in seconds) | 4 | Integer |
| max_delay | Specifies the maximum time to wait before retrying (in seconds) | 60 | Integer |
| enable_retry | enabling/disable the Exponential Retry mechanism | false | Boolean |


### For more information about these methods and their parameters, see the [API documentation](https://docs.novu.co/api-reference).

## Contributing
Expand Down
7 changes: 3 additions & 4 deletions lib/novu/api/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,14 @@ def request(http_method, path, options)
end

response = self.class.send(http_method, path, options)
puts response.code, response.code == 401

if ! [401, 403, 409, 500, 502, 503, 504].include?(response.code) && ! @enable_retry
response
elsif @enable_retry
@retry_attempts += 1

puts "retrying requests now.... #{@retry_attempts}"

if @retry_attempts < @max_retries
@retry_attempts += 1

@backoff.intervals.each do |interval|
sleep(interval)
request(http_method, path, options)
Expand Down
13 changes: 12 additions & 1 deletion lib/novu/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ class Client

attr_accessor :enable_retry, :max_retries, :initial_delay, :max_delay, :idempotency_key

# @param `access_token` [String]
# @param `idempotency_key` [String]
# @param `enable_retry` [Boolean]
# @param `retry_config` [Hash]
# - max_retries [Integer]
# - initial_delay [Integer]
# - max_delay [Integer]
def initialize(access_token: nil, idempotency_key: nil, enable_retry: false, retry_config: {} )
raise ArgumentError, "Api Key cannot be blank or nil" if access_token.blank?

Expand Down Expand Up @@ -71,8 +78,12 @@ def initialize(access_token: nil, idempotency_key: nil, enable_retry: false, ret

private

# @retun [Hash]
# - max_retries [Integer]
# - initial_delay [Integer]
# - max_delay [Integer]
def defaults_retry_config
{ max_retries: 3, initial_delay: 4.0, max_delay: 60.0 }
{ max_retries: 1, initial_delay: 4, max_delay: 60 }
end
end
end

0 comments on commit 3ff5d49

Please sign in to comment.