Liking cljdoc? Tell your friends :D

safely.core


*sleepless-mode*clj

source

circuit-breaker-infoclj

(circuit-breaker-info)
(circuit-breaker-info circuit-breaker-name)

It returns a map with information regarding one circuit breaker (if a name is specified) or all of them. the structure contains the status, some counters, and sampled responses.

It returns a map with information regarding one circuit breaker
(if a name is specified) or all of them. the structure contains
 the status, some counters, and sampled responses.
sourceraw docstring

randomclj

(random base :+/- pct)
(random :min min :max max)

Returns a uniformly distributed random value within certain boundaries.

It can be used as following:

  • (random :min 100 :max 300) It returns a random integer between 100 and 300 (excluded)

  • (random 300 :+/- 0.50) It returns a random integer uniformly distributed between 150 and 450 (excluded)

Returns a uniformly distributed random value within certain boundaries.

It can be used as following:

- `(random :min 100 :max 300)` It returns a random integer between `100` and
  `300` (excluded)

- `(random 300 :+/- 0.50)` It returns a random integer uniformly distributed
  between `150` and `450` (excluded)

sourceraw docstring

safelycljmacro

(safely & body :on-error & handling-options)

Safely offers a safe code execution against Exceptions. It offers a declarative approach to a large number of handling strategies. Usage:

    (safely
       & code
       :on-error
       & handling-options)

The available handling options are:

  • :default <value> will return <value> if the execution of <code> fails.

Available retry policies:

  • :max-retries <n> or :forever will retry the code block in case of failures for a maximum of <n> times. Since this express the 're-tries' you should assume the total number of attempts to be at most n + 1. When set to :forever it will retry indefinitely. Used in conjunction with :default will retry first, and if all attempts fails the default value will be returned instead. The time between each retry is determined by one of the following options, the default strategy is: :random-exp-backoff

  • :retry-delay [:fix <millis>] (NOT RECOMMENDED) To sleep a fix amount of time between retries.

  • :retry-delay [:random-range :min <millis> :max <millis>] To sleep a random amount of time between retries within certain a :min and :max time.

  • :retry-delay [:random <millis> :+/- <pct>] To sleep a random amount of time <millis> each retry which is randomized with a +/- <pct> of the base value. Eg: :random 5000 :+/- 0.35 will sleep 5s with +/- 35%

  • :retry-delay [:random-exp-backoff :base <millis> :+/- <pct>] :retry-delay [:random-exp-backoff :base <millis> :+/- <pct> :max <millis>] To sleep a random amount of time which will exponentially grow between retries. (see documentation for more info)

  • :retry-delay [:rand-cycle [<millis1> <millis2> ... <millisN>] :+/- <pct>] To sleep cycling the given list and randomizing by +/- <pct>. On the first retry will wait <millis1> +/- <pct>, on the second retry will wait <millis2> +/- <pct> as so on. If the :max-retries exceeds the number of waiting time it will restart from <millis1>.

  • :retryable-error? (fn [exception] true) In cases where only certain type of errors can be retried but not others, you can define a function which takes in input the exception raised and returns whether this exception should be retried or not. If the error isn't retryable the exception will be thrown up to be handled outside of the safely block. For example if you wish not to retry ArithmeticException you could use something like: :retryable-error? #(not (#{ArithmeticException} (type %)))

  • :rethrow with one of :original, :wrapped, :legacy, (fn [exception] true) It can be one of the following values: :original, :wrapped, :legacy or (fn [exception] true) a function which takes a java.lang.Throwable and returns a java.lang.Throwable. Use :rethrow :original to rethrow the exception that was generated inside the safely block to the caller. Please note that if you are using a circuit-breaker, the exception received will depend on the current state of the circuit and it could be an ex-info exception with :cause :circuit-open. Use :rethrow :wrapped to rethrow and ex-info exception with the current values of the safely internal data and the original exception as the cause. Use :rethrow :legacy (default) to maintain the behaviour of version 0.7.0 or earlier versions, which unfortunately was a mix of the two. Use :return (fn [exception] (ex-info "my custom exception" {} exception)) to return a new (or the same) exception. This option provides the opportunity to conform the exception thrown to the caller.

  • :failed? (fn [result] false) You can provide a predicate function to determine whether the result of the body expression is a failed result of not. The failed predicate can be used to produce the same delayed retry with APIs which do not throw exceptions. For example consider a HTTP request which returns the status instead of failing. With the failed predicate function you could have exponential back-off retry when the HTTP response contains a HTTP status code which is not 2xx. Another use of this is for example in APIs which support polling. The failed predicate function can be used to determine whether the polling call returned valid items or it was empty, and if it is empty then it is possible to slow down the polling using the default exponential back-off. The :failed? predicate function is executed only on successful body execution and only when provided. If :failed? returns true, then the execution is considered failed, even though there is no exception, and it will follow the exceptional retry logic as normal. NOTE: this function must be a pure function as it could be called multiple times.

Circuit breaker options:

  • :circuit-breaker <:operation-name> This options is required to activate the circuit breaker. It identifies the specific operation the circuit breaker is protecting. The name is used also to track resources and stats for the operation. NOTE: don't use high cardinality values or randomly generate values to avoid the risk of running out of memory. Name the circuit breaker after the operation it is trying to accomplish.

  • :thread-pool-size 10 This is the size of the dedicated thread pool for this operation. The default size should work fine for most of high volume operations. Before changing this value please refer to the following link: https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool about how to correctly size circuit breaker thread pools.

  • :queue-size 5 It sets how big should be the queue for the circuit breaker which it is in front of the thread pool. A good value for this is about 30%-50% of the thread pool size. The queue should be used only to cope with a small surge in requests. Be aware that the bigger is the queue the more latency will be added processing your requests. Before changing this value please refer to the following link: https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool about how to correctly size circuit breaker thread pools.

  • :sample-size 100 It sets how big it is the buffer that samples the most recent requests. This it can be useful to see what happened to the recent requests and decide whether to trip the circuit open.

  • :timeout 3000 (in millis) (default: not set) It sets a timeout on each individual request sent in the circuit breaker. It only works when used in conjunction with the circuit breaker. If not set the caller will wait until the thread has completed to process the request and returned a value. When set, if the thread process the request before the timeout expires the resulting value is returned to the caller, otherwise a timeout exception is thrown.

  • :cancel-on-timeout :always It controls what happen to the request when a timeout wait time is reached. You can choose when you want to cancel the request. Available options are: :never, :if-not-running, :always. :if-not-running cancels the request only if it is still in the queue and the execution is not started yet.

  • :counters-buckets 10 The number of 1-second buckets with counters for the number of requests succeeded, failed, timed out, etc. Only the most recent requests buckets are kept.

  • :circuit-breaker-strategy :failure-threshold This is the strategy used to trip the circuit breaker open. Currently only this strategy is supported.

  • :failure-threshold 0.50 (50%) Only used when :circuit-breaker-strategy is :failure-threshold. It sets the threshold which when crossed, it will trip the circuit open. It requires at least 3 requests in the counters to evaluate the threshold. Otherwise it is closed by default.

  • :grace-period 3000 (in millis) When the circuit is tripped open, it will reject all the requests within the grace period. After this period is passed then it will change state and go to the half-open state.

  • :half-open-strategy :linear-ramp-up When the circuit moves from :open state to :half-open the circuit breaker has to decide which requests to let through and which reject immediately. This is the strategy used to evaluate which requests are to be tried in order to determine whether the circuit can be closed again. Currently only this strategy is supported.

  • :ramp-up-period 5000 (in millis) Only used when :half-open-strategy is :linear-ramp-up. The :linear-ramp-up will pick randomly a increasing number of requests and let them through and evaluate the result.

Exceptions are logged automatically. Here some options to control logging

  • :message "a custom error message" To log the error with a custom message which helps to contextualize the error message.

  • :log-errors false (default true) To disable logging

  • :log-level <level> (default :warn) To log the errors with a given error level, available options: :trace, :debug, :info, :warn, :error, :fatal

  • :log-stacktrace false (default true) To disable stacktrace reporting in the logs.

  • :log-ns "your.namespace" (default *ns*) To select the namespace logger. It defaults to the current ns.

  • It is possible to control the logging of the individual attempts by setting the following options:

    • :log-inner-errors
    • :log-inner-level
    • :log-inner-stacktrace
    • :log-inner-ns All the :log-inner-* if no value is provided, they default to the value of the :log-* options. There are useful to reduce the log noise on individual attempts.

Tracking options:

  • :tracking :disabled (default :enabled) Whether to enable or disable tracking.

  • :track-as ::action-name Will use the given keyword or string as name for the event. Use names which will be clearly specifying the which part of your code you are tracking, for example: ::db-save and ::fect-user clearly specify which action if currently failing. Use namespaced keywords, or fully-qualified actions "mymodule.myaction" for avoiding name-conflicts. Use mulog/set-global-context! to add general info such application name, version, environment, host etc. The tracking is done via μ/log. If :track-as is not provided, its source code location will be used instead. All safely blocks are tracked by default. If you wish put :track-as nil the tracking event won't be collected, but the tracking context will be created..

  • :tracking-tags [:key1 :val1, :key2 :val2, ...] (default []) A vector of key/value pairs to include in the tracking event. They are useful to give more context to the event, so that when you read the event you have more info.

    Example: :tracking-tags [:batch-size 30 :user user-id]

  • :tracking-capture (fn [result] {:k1 :v1, :k2 :v2}) (default nil) Is a function which returns the restult of the evaluation and capture some information from the result. This is useful, for example if you want to capture the http-status of a remote call. it returns a map or nil, the returned map will be merged with the tracking event.

    Example: :tracking-capture (fn [r] {:http-status (:http-status r)})

(see website for more documentation: https://github.com/BrunoBonacci/safely)

Safely offers a safe code execution against Exceptions.
 It offers a declarative approach to a large number of handling strategies.
 Usage:

        (safely
           & code
           :on-error
           & handling-options)

 The available handling options are:

   - `:default <value>`
      will return `<value>` if the execution of `<code>` fails.


 Available retry policies:

   - `:max-retries <n>` or `:forever`
      will retry the code block in case of failures for a maximum
      of `<n>` times. Since this express the 're-tries' you should assume
      the total number of attempts to be at most `n + 1`.
      When set to `:forever` it will retry indefinitely.
      Used in conjunction with `:default` will retry first, and if
      all attempts fails the default value will be returned instead.
      The time between each retry is determined by one of the
      following options, the default strategy is: `:random-exp-backoff`


   - `:retry-delay [:fix <millis>]` *(NOT RECOMMENDED)*
      To sleep a fix amount of time between retries.

   - `:retry-delay [:random-range :min <millis> :max <millis>]`
      To sleep a random amount of time between retries within
      certain a `:min` and `:max` time.

   - `:retry-delay [:random <millis> :+/- <pct>]`
      To sleep a random amount of time `<millis>` each retry which
      is randomized with a +/- `<pct>` of the base value.
      Eg: `:random 5000 :+/- 0.35` will sleep 5s with `+/- 35%`

   - `:retry-delay [:random-exp-backoff :base <millis> :+/- <pct>]`
     `:retry-delay [:random-exp-backoff :base <millis> :+/- <pct> :max <millis>]`
      To sleep a random amount of time which will exponentially
      grow between retries. (see documentation for more info)

   - `:retry-delay [:rand-cycle [<millis1> <millis2> ... <millisN>] :+/- <pct>]`
      To sleep cycling the given list and randomizing by +/- <pct>.
      On the first retry will wait `<millis1> +/- <pct>`, on the second
      retry will wait `<millis2> +/- <pct>` as so on. If the `:max-retries`
      exceeds the number of waiting time it will restart from `<millis1>`.

   - `:retryable-error? (fn [exception] true)`
      In cases where only certain type of errors can be retried but
      not others, you can define a function which takes in input
      the exception raised and returns whether this exception
      should be retried or not. If the error isn't retryable
      the exception will be thrown up to be handled outside
      of the safely block.
      For example if you wish not to retry ArithmeticException
      you could use something like:
      `:retryable-error? #(not (#{ArithmeticException} (type %)))`

   - `:rethrow` with one of `:original`, `:wrapped`, `:legacy`, `(fn [exception] true)`
      It can be one of the following values: `:original`, `:wrapped`, `:legacy`
      or `(fn [exception] true)` a function which takes a java.lang.Throwable
      and returns a java.lang.Throwable.
      Use `:rethrow :original` to rethrow the exception that was generated inside
      the safely block to the caller. Please note that if you are using
      a circuit-breaker, the exception received will depend on the current state
      of the circuit and it could be an ex-info exception with `:cause :circuit-open`.
      Use `:rethrow :wrapped` to rethrow and ex-info exception with the current
      values of the safely internal data and the original exception as the cause.
      Use `:rethrow :legacy` (default) to maintain the behaviour of version 0.7.0
      or earlier versions, which unfortunately was a mix of the two.
      Use `:return (fn [exception] (ex-info "my custom exception" {} exception))`
      to return a new (or the same) exception. This option provides the opportunity
      to conform the exception thrown to the caller.

   - `:failed? (fn [result] false)`
      You can provide a predicate function to determine whether the result
      of the body expression is a `failed` result of not.
      The failed predicate can be used to produce the same delayed retry
      with APIs which do not throw exceptions. For example consider a
      HTTP request which returns the status instead of failing.
      With the failed predicate function you could have exponential back-off
      retry when the HTTP response contains a HTTP status code which is not `2xx`.
      Another use of this is for example in APIs which support polling.
      The failed predicate function can be used to determine whether the polling
      call returned valid items or it was empty, and if it is empty then it is
      possible to slow down the polling using the default exponential back-off.
      The `:failed?` predicate function is executed only on successful body
      execution and only when provided. If `:failed?` returns true, then the
      execution is considered failed, even though there is no exception,
      and it will follow the exceptional retry logic as normal.
      NOTE: this function must be a pure function as it could be called
      multiple times.

Circuit breaker options:

   - `:circuit-breaker <:operation-name>`
      This options is required to activate the circuit breaker.
      It identifies the specific operation the circuit breaker is
      protecting. The name is used also to track resources and stats
      for the operation. NOTE: don't use high cardinality values or
      randomly generate values to avoid the risk of running out of
      memory. Name the circuit breaker after the operation it is
      trying to accomplish.

   - `:thread-pool-size  10`
      This is the size of the dedicated thread pool for this operation.
      The default size should work fine for most of high volume operations.
      Before changing this value please refer to the following link:
      https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool
      about how to correctly size circuit breaker thread pools.

   - `:queue-size 5`
      It sets how big should be the queue for the circuit breaker
      which it is in front of the thread pool. A good value for this
      is about 30%-50% of the thread pool size. The queue should be used
      only to cope with a small surge in requests. Be aware that the bigger
      is the queue the more latency will be added processing your requests.
      Before changing this value please refer to the following link:
      https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool
      about how to correctly size circuit breaker thread pools.

   - `:sample-size 100`
      It sets how big it is the buffer that samples the most recent
      requests. This it can be useful to see what happened to
      the recent requests and decide whether to trip the circuit open.

   - `:timeout 3000` *(in millis) (default: not set)*
      It sets a timeout on each individual request sent in the circuit
      breaker. It only works when used in conjunction with the circuit
      breaker. If not set the caller will wait until the thread has
      completed to process the request and returned a value.
      When set, if the thread process the request before the timeout
      expires the resulting value is returned to the caller, otherwise
      a timeout exception is thrown.

   - `:cancel-on-timeout :always` It controls what happen to the request
      when a timeout wait time is reached.  You can choose when you want
      to cancel the request. Available options are: `:never`,
      `:if-not-running`, `:always`. `:if-not-running` cancels the request
      only if it is still in the queue and the execution is not started
      yet.

   - `:counters-buckets 10`
      The number of 1-second buckets with counters for the number of
      requests succeeded, failed, timed out, etc. Only the most
      recent requests buckets are kept.

   - `:circuit-breaker-strategy :failure-threshold`
      This is the strategy used to trip the circuit breaker open.
      Currently only this strategy is supported.

   - `:failure-threshold 0.50` *(50%)*
      Only used when `:circuit-breaker-strategy` is `:failure-threshold`.
      It sets the threshold which when crossed, it will trip the
      circuit open. It requires at least 3 requests in the counters
      to evaluate the threshold. Otherwise it is closed by default.

   - `:grace-period 3000` *(in millis)*
      When the circuit is tripped open, it will reject all the requests
      within the grace period. After this period is passed then it will
      change state and go to the half-open state.

   - `:half-open-strategy :linear-ramp-up`
      When the circuit moves from `:open` state to `:half-open` the
      circuit breaker has to decide which requests to let through and
      which reject immediately.  This is the strategy used to evaluate
      which requests are to be tried in order to determine whether the
      circuit can be closed again.  Currently only this strategy is
      supported.

   - `:ramp-up-period 5000` *(in millis)*
      Only used when :half-open-strategy is `:linear-ramp-up`.
      The `:linear-ramp-up` will pick randomly a increasing number
      of requests and let them through and evaluate the result.


 Exceptions are logged automatically. Here some options to control logging

   - `:message "a custom error message"`
      To log the error with a custom message which helps to contextualize
      the error message.

   - `:log-errors false` *(default true)*
      To disable logging

   - `:log-level <level>` *(default :warn)*
      To log the errors with a given error level, available options:
      `:trace`, `:debug`, `:info`, `:warn`, `:error`, `:fatal`

   - `:log-stacktrace false` *(default true)*
      To disable stacktrace reporting in the logs.

   - `:log-ns "your.namespace"` (default `*ns*`)
      To select the namespace logger. It defaults to the current ns.

   - It is possible to control the logging of the individual attempts
     by setting the following options:
     - `:log-inner-errors`
     - `:log-inner-level`
     - `:log-inner-stacktrace`
     - `:log-inner-ns`
    All the `:log-inner-*` if no value is provided, they default to the
    value of the `:log-*` options. There are useful to reduce the log
    noise on individual attempts.


 Tracking options:

   - `:tracking :disabled` *(default `:enabled`)*
      Whether to enable or disable tracking.

   - `:track-as ::action-name`
      Will use the given keyword or string as name for the event. Use
      names which will be clearly specifying the which part of your code
      you are tracking, for example: `::db-save` and `::fect-user` clearly
      specify which action if currently failing. Use namespaced keywords,
      or fully-qualified actions "mymodule.myaction" for avoiding
      name-conflicts.  Use `mulog/set-global-context!` to add general info
      such application name, version, environment, host etc. The tracking
      is done via [***μ/log***](https://github.com/BrunoBonacci/mulog).  If
      `:track-as` is not provided, its source code location will be used
      instead. _All `safely` blocks are tracked by default._ If you wish
      put `:track-as nil` the tracking event won't be collected, but
      the tracking context will be created..

   - `:tracking-tags [:key1 :val1, :key2 :val2, ...]` *(default `[]`)*
      A vector of key/value pairs to include in the tracking event.
      They are useful to give more context to the event, so that
      when you read the event you have more info.

      Example:
      `:tracking-tags [:batch-size 30 :user user-id]`

   - `:tracking-capture (fn [result] {:k1 :v1, :k2 :v2})` *(default `nil`)*
      Is a function which returns the restult of the evaluation and
      capture some information from the result.  This is useful, for
      example if you want to capture the http-status of a remote call.  it
      returns a map or `nil`, the returned map will be merged with the
      tracking event.

      Example:
      `:tracking-capture (fn [r] {:http-status (:http-status r)})`


(see website for more documentation: https://github.com/BrunoBonacci/safely)
sourceraw docstring

safely-fnclj

(safely-fn f & {:as opts})

Safely offers a safe code execution against Exceptions. It offers a declarative approach to a large number of handling strategies. Usage:

    (safely-fn
       f
       & handling-options)

The available handling options are:

  • :default <value> will return <value> if the execution of <code> fails.

Available retry policies:

  • :max-retries <n> or :forever will retry the code block in case of failures for a maximum of <n> times. Since this express the 're-tries' you should assume the total number of attempts to be at most n + 1. When set to :forever it will retry indefinitely. Used in conjunction with :default will retry first, and if all attempts fails the default value will be returned instead. The time between each retry is determined by one of the following options, the default strategy is: :random-exp-backoff

  • :retry-delay [:fix <millis>] (NOT RECOMMENDED) To sleep a fix amount of time between retries.

  • :retry-delay [:random-range :min <millis> :max <millis>] To sleep a random amount of time between retries within certain a :min and :max time.

  • :retry-delay [:random <millis> :+/- <pct>] To sleep a random amount of time <millis> each retry which is randomized with a +/- <pct> of the base value. Eg: :random 5000 :+/- 0.35 will sleep 5s with +/- 35%

  • :retry-delay [:random-exp-backoff :base <millis> :+/- <pct>] :retry-delay [:random-exp-backoff :base <millis> :+/- <pct> :max <millis>] To sleep a random amount of time which will exponentially grow between retries. (see documentation for more info)

  • :retry-delay [:rand-cycle [<millis1> <millis2> ... <millisN>] :+/- <pct>] To sleep cycling the given list and randomizing by +/- <pct>. On the first retry will wait <millis1> +/- <pct>, on the second retry will wait <millis2> +/- <pct> as so on. If the :max-retries exceeds the number of waiting time it will restart from <millis1>.

  • :retryable-error? (fn [exception] true) In cases where only certain type of errors can be retried but not others, you can define a function which takes in input the exception raised and returns whether this exception should be retried or not. If the error isn't retryable the exception will be thrown up to be handled outside of the safely block. For example if you wish not to retry ArithmeticException you could use something like: :retryable-error? #(not (#{ArithmeticException} (type %)))

  • :rethrow with one of :original, :wrapped, :legacy, (fn [exception] true) It can be one of the following values: :original, :wrapped, :legacy or (fn [exception] true) a function which takes a java.lang.Throwable and returns a java.lang.Throwable. Use :rethrow :original to rethrow the exception that was generated inside the safely block to the caller. Please note that if you are using a circuit-breaker, the exception received will depend on the current state of the circuit and it could be an ex-info exception with :cause :circuit-open. Use :rethrow :wrapped to rethrow and ex-info exception with the current values of the safely internal data and the original exception as the cause. Use :rethrow :legacy (default) to maintain the behaviour of version 0.7.0 or earlier versions, which unfortunately was a mix of the two. Use :return (fn [exception] (ex-info "my custom exception" {} exception)) to return a new (or the same) exception. This option provides the opportunity to conform the exception thrown to the caller.

  • :failed? (fn [result] false) You can provide a predicate function to determine whether the result of the body expression is a failed result of not. The failed predicate can be used to produce the same delayed retry with APIs which do not throw exceptions. For example consider a HTTP request which returns the status instead of failing. With the failed predicate function you could have exponential back-off retry when the HTTP response contains a HTTP status code which is not 2xx. Another use of this is for example in APIs which support polling. The failed predicate function can be used to determine whether the polling call returned valid items or it was empty, and if it is empty then it is possible to slow down the polling using the default exponential back-off. The :failed? predicate function is executed only on successful body execution and only when provided. If :failed? returns true, then the execution is considered failed, even though there is no exception, and it will follow the exceptional retry logic as normal. NOTE: this function must be a pure function as it could be called multiple times.

Circuit breaker options:

  • :circuit-breaker <:operation-name> This options is required to activate the circuit breaker. It identifies the specific operation the circuit breaker is protecting. The name is used also to track resources and stats for the operation. NOTE: don't use high cardinality values or randomly generate values to avoid the risk of running out of memory. Name the circuit breaker after the operation it is trying to accomplish.

  • :thread-pool-size 10 This is the size of the dedicated thread pool for this operation. The default size should work fine for most of high volume operations. Before changing this value please refer to the following link: https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool about how to correctly size circuit breaker thread pools.

  • :queue-size 5 It sets how big should be the queue for the circuit breaker which it is in front of the thread pool. A good value for this is about 30%-50% of the thread pool size. The queue should be used only to cope with a small surge in requests. Be aware that the bigger is the queue the more latency will be added processing your requests. Before changing this value please refer to the following link: https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool about how to correctly size circuit breaker thread pools.

  • :sample-size 100 It sets how big it is the buffer that samples the most recent requests. This it can be useful to see what happened to the recent requests and decide whether to trip the circuit open.

  • :timeout 3000 (in millis) (default: not set) It sets a timeout on each individual request sent in the circuit breaker. It only works when used in conjunction with the circuit breaker. If not set the caller will wait until the thread has completed to process the request and returned a value. When set, if the thread process the request before the timeout expires the resulting value is returned to the caller, otherwise a timeout exception is thrown.

  • :cancel-on-timeout :always It controls what happen to the request when a timeout wait time is reached. You can choose when you want to cancel the request. Available options are: :never, :if-not-running, :always. :if-not-running cancels the request only if it is still in the queue and the execution is not started yet.

  • :counters-buckets 10 The number of 1-second buckets with counters for the number of requests succeeded, failed, timed out, etc. Only the most recent requests buckets are kept.

  • :circuit-breaker-strategy :failure-threshold This is the strategy used to trip the circuit breaker open. Currently only this strategy is supported.

  • :failure-threshold 0.50 (50%) Only used when :circuit-breaker-strategy is :failure-threshold. It sets the threshold which when crossed, it will trip the circuit open. It requires at least 3 requests in the counters to evaluate the threshold. Otherwise it is closed by default.

  • :grace-period 3000 (in millis) When the circuit is tripped open, it will reject all the requests within the grace period. After this period is passed then it will change state and go to the half-open state.

  • :half-open-strategy :linear-ramp-up When the circuit moves from :open state to :half-open the circuit breaker has to decide which requests to let through and which reject immediately. This is the strategy used to evaluate which requests are to be tried in order to determine whether the circuit can be closed again. Currently only this strategy is supported.

  • :ramp-up-period 5000 (in millis) Only used when :half-open-strategy is :linear-ramp-up. The :linear-ramp-up will pick randomly a increasing number of requests and let them through and evaluate the result.

Exceptions are logged automatically. Here some options to control logging

  • :message "a custom error message" To log the error with a custom message which helps to contextualize the error message.

  • :log-errors false (default true) To disable logging

  • :log-level <level> (default :warn) To log the errors with a given error level, available options: :trace, :debug, :info, :warn, :error, :fatal

  • :log-stacktrace false (default true) To disable stacktrace reporting in the logs.

  • :log-ns "your.namespace" (default safely.log) To select the namespace logger. It defaults to the safely.log.

  • It is possible to control the logging of the individual attempts by setting the following options:

    • :log-inner-errors
    • :log-inner-level
    • :log-inner-stacktrace
    • :log-inner-ns All the :log-inner-* if no value is provided, they default to the value of the :log-* options. There are useful to reduce the log noise on individual attempts.

Tracking options:

  • :tracking :disabled (default :enabled) Whether to enable or disable tracking.

  • :track-as ::action-name Will use the given keyword or string as name for the event. Use names which will be clearly specifying the which part of your code you are tracking, for example: ::db-save and ::fect-user clearly specify which action if currently failing. Use namespaced keywords, or fully-qualified actions "mymodule.myaction" for avoiding name-conflicts. Use mulog/set-global-context! to add general info such application name, version, environment, host etc. The tracking is done via μ/log. If :track-as is not provided, its source code location will be used instead. All safely blocks are tracked by default. If you wish put :track-as nil the tracking event won't be collected, but the tracking context will be created..

  • :tracking-tags [:key1 :val1, :key2 :val2, ...] (default []) A vector of key/value pairs to include in the tracking event. They are useful to give more context to the event, so that when you read the event you have more info.

    Example: :tracking-tags [:batch-size 30 :user user-id]

  • :tracking-capture (fn [result] {:k1 :v1, :k2 :v2}) (default nil) Is a function which returns the restult of the evaluation and capture some information from the result. This is useful, for example if you want to capture the http-status of a remote call. it returns a map or nil, the returned map will be merged with the tracking event.

    Example: :tracking-capture (fn [r] {:http-status (:http-status r)})

(see website for more documentation: https://github.com/BrunoBonacci/safely)

Safely offers a safe code execution against Exceptions.
 It offers a declarative approach to a large number of handling strategies.
 Usage:

        (safely-fn
           f
           & handling-options)

 The available handling options are:

   - `:default <value>`
      will return `<value>` if the execution of `<code>` fails.


 Available retry policies:

   - `:max-retries <n>` or `:forever`
      will retry the code block in case of failures for a maximum
      of `<n>` times. Since this express the 're-tries' you should assume
      the total number of attempts to be at most `n + 1`.
      When set to `:forever` it will retry indefinitely.
      Used in conjunction with `:default` will retry first, and if
      all attempts fails the default value will be returned instead.
      The time between each retry is determined by one of the
      following options, the default strategy is: `:random-exp-backoff`


   - `:retry-delay [:fix <millis>]` *(NOT RECOMMENDED)*
      To sleep a fix amount of time between retries.

   - `:retry-delay [:random-range :min <millis> :max <millis>]`
      To sleep a random amount of time between retries within
      certain a `:min` and `:max` time.

   - `:retry-delay [:random <millis> :+/- <pct>]`
      To sleep a random amount of time `<millis>` each retry which
      is randomized with a +/- `<pct>` of the base value.
      Eg: `:random 5000 :+/- 0.35` will sleep 5s with `+/- 35%`

   - `:retry-delay [:random-exp-backoff :base <millis> :+/- <pct>]`
     `:retry-delay [:random-exp-backoff :base <millis> :+/- <pct> :max <millis>]`
      To sleep a random amount of time which will exponentially
      grow between retries. (see documentation for more info)

   - `:retry-delay [:rand-cycle [<millis1> <millis2> ... <millisN>] :+/- <pct>]`
      To sleep cycling the given list and randomizing by +/- <pct>.
      On the first retry will wait `<millis1> +/- <pct>`, on the second
      retry will wait `<millis2> +/- <pct>` as so on. If the `:max-retries`
      exceeds the number of waiting time it will restart from `<millis1>`.

   - `:retryable-error? (fn [exception] true)`
      In cases where only certain type of errors can be retried but
      not others, you can define a function which takes in input
      the exception raised and returns whether this exception
      should be retried or not. If the error isn't retryable
      the exception will be thrown up to be handled outside
      of the safely block.
      For example if you wish not to retry ArithmeticException
      you could use something like:
      `:retryable-error? #(not (#{ArithmeticException} (type %)))`

   - `:rethrow` with one of `:original`, `:wrapped`, `:legacy`, `(fn [exception] true)`
      It can be one of the following values: `:original`, `:wrapped`, `:legacy`
      or `(fn [exception] true)` a function which takes a java.lang.Throwable
      and returns a java.lang.Throwable.
      Use `:rethrow :original` to rethrow the exception that was generated inside
      the safely block to the caller. Please note that if you are using
      a circuit-breaker, the exception received will depend on the current state
      of the circuit and it could be an ex-info exception with `:cause :circuit-open`.
      Use `:rethrow :wrapped` to rethrow and ex-info exception with the current
      values of the safely internal data and the original exception as the cause.
      Use `:rethrow :legacy` (default) to maintain the behaviour of version 0.7.0
      or earlier versions, which unfortunately was a mix of the two.
      Use `:return (fn [exception] (ex-info "my custom exception" {} exception))`
      to return a new (or the same) exception. This option provides the opportunity
      to conform the exception thrown to the caller.

   - `:failed? (fn [result] false)`
      You can provide a predicate function to determine whether the result
      of the body expression is a `failed` result of not.
      The failed predicate can be used to produce the same delayed retry
      with APIs which do not throw exceptions. For example consider a
      HTTP request which returns the status instead of failing.
      With the failed predicate function you could have exponential back-off
      retry when the HTTP response contains a HTTP status code which is not `2xx`.
      Another use of this is for example in APIs which support polling.
      The failed predicate function can be used to determine whether the polling
      call returned valid items or it was empty, and if it is empty then it is
      possible to slow down the polling using the default exponential back-off.
      The `:failed?` predicate function is executed only on successful body
      execution and only when provided. If `:failed?` returns true, then the
      execution is considered failed, even though there is no exception,
      and it will follow the exceptional retry logic as normal.
      NOTE: this function must be a pure function as it could be called
      multiple times.

Circuit breaker options:

   - `:circuit-breaker <:operation-name>`
      This options is required to activate the circuit breaker.
      It identifies the specific operation the circuit breaker is
      protecting. The name is used also to track resources and stats
      for the operation. NOTE: don't use high cardinality values or
      randomly generate values to avoid the risk of running out of
      memory. Name the circuit breaker after the operation it is
      trying to accomplish.

   - `:thread-pool-size  10`
      This is the size of the dedicated thread pool for this operation.
      The default size should work fine for most of high volume operations.
      Before changing this value please refer to the following link:
      https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool
      about how to correctly size circuit breaker thread pools.

   - `:queue-size 5`
      It sets how big should be the queue for the circuit breaker
      which it is in front of the thread pool. A good value for this
      is about 30%-50% of the thread pool size. The queue should be used
      only to cope with a small surge in requests. Be aware that the bigger
      is the queue the more latency will be added processing your requests.
      Before changing this value please refer to the following link:
      https://github.com/BrunoBonacci/safely#how-to-size-the-thread-pool
      about how to correctly size circuit breaker thread pools.

   - `:sample-size 100`
      It sets how big it is the buffer that samples the most recent
      requests. This it can be useful to see what happened to
      the recent requests and decide whether to trip the circuit open.

   - `:timeout 3000` *(in millis) (default: not set)*
      It sets a timeout on each individual request sent in the circuit
      breaker. It only works when used in conjunction with the circuit
      breaker. If not set the caller will wait until the thread has
      completed to process the request and returned a value.
      When set, if the thread process the request before the timeout
      expires the resulting value is returned to the caller, otherwise
      a timeout exception is thrown.

   - `:cancel-on-timeout :always` It controls what happen to the request
      when a timeout wait time is reached.  You can choose when you want
      to cancel the request. Available options are: `:never`,
      `:if-not-running`, `:always`. `:if-not-running` cancels the request
      only if it is still in the queue and the execution is not started
      yet.

   - `:counters-buckets 10`
      The number of 1-second buckets with counters for the number of
      requests succeeded, failed, timed out, etc. Only the most
      recent requests buckets are kept.

   - `:circuit-breaker-strategy :failure-threshold`
      This is the strategy used to trip the circuit breaker open.
      Currently only this strategy is supported.

   - `:failure-threshold 0.50` *(50%)*
      Only used when `:circuit-breaker-strategy` is `:failure-threshold`.
      It sets the threshold which when crossed, it will trip the
      circuit open. It requires at least 3 requests in the counters
      to evaluate the threshold. Otherwise it is closed by default.

   - `:grace-period 3000` *(in millis)*
      When the circuit is tripped open, it will reject all the requests
      within the grace period. After this period is passed then it will
      change state and go to the half-open state.

   - `:half-open-strategy :linear-ramp-up`
      When the circuit moves from `:open` state to `:half-open` the
      circuit breaker has to decide which requests to let through and
      which reject immediately.  This is the strategy used to evaluate
      which requests are to be tried in order to determine whether the
      circuit can be closed again.  Currently only this strategy is
      supported.

   - `:ramp-up-period 5000` *(in millis)*
      Only used when :half-open-strategy is `:linear-ramp-up`.
      The `:linear-ramp-up` will pick randomly a increasing number
      of requests and let them through and evaluate the result.


 Exceptions are logged automatically. Here some options to control logging

   - `:message "a custom error message"`
      To log the error with a custom message which helps to contextualize
      the error message.

   - `:log-errors false` *(default true)*
      To disable logging

   - `:log-level <level>` *(default :warn)*
      To log the errors with a given error level, available options:
      `:trace`, `:debug`, `:info`, `:warn`, `:error`, `:fatal`

   - `:log-stacktrace false` *(default true)*
      To disable stacktrace reporting in the logs.

   - `:log-ns "your.namespace"` *(default `safely.log`)*
      To select the namespace logger. It defaults to the `safely.log`.

   - It is possible to control the logging of the individual attempts
     by setting the following options:
     - `:log-inner-errors`
     - `:log-inner-level`
     - `:log-inner-stacktrace`
     - `:log-inner-ns`
    All the `:log-inner-*` if no value is provided, they default to the
    value of the `:log-*` options. There are useful to reduce the log
    noise on individual attempts.


 Tracking options:

   - `:tracking :disabled` *(default `:enabled`)*
      Whether to enable or disable tracking.

   - `:track-as ::action-name`
      Will use the given keyword or string as name for the event. Use
      names which will be clearly specifying the which part of your code
      you are tracking, for example: `::db-save` and `::fect-user` clearly
      specify which action if currently failing. Use namespaced keywords,
      or fully-qualified actions "mymodule.myaction" for avoiding
      name-conflicts.  Use `mulog/set-global-context!` to add general info
      such application name, version, environment, host etc. The tracking
      is done via [***μ/log***](https://github.com/BrunoBonacci/mulog).  If
      `:track-as` is not provided, its source code location will be used
      instead. _All `safely` blocks are tracked by default._ If you wish
      put `:track-as nil` the tracking event won't be collected, but
      the tracking context will be created..

   - `:tracking-tags [:key1 :val1, :key2 :val2, ...]` *(default `[]`)*
      A vector of key/value pairs to include in the tracking event.
      They are useful to give more context to the event, so that
      when you read the event you have more info.

      Example:
      `:tracking-tags [:batch-size 30 :user user-id]`

   - `:tracking-capture (fn [result] {:k1 :v1, :k2 :v2})` *(default `nil`)*
      Is a function which returns the restult of the evaluation and
      capture some information from the result.  This is useful, for
      example if you want to capture the http-status of a remote call.  it
      returns a map or `nil`, the returned map will be merged with the
      tracking event.

      Example:
      `:tracking-capture (fn [r] {:http-status (:http-status r)})`


(see website for more documentation: https://github.com/BrunoBonacci/safely)
sourceraw docstring

shutdown-poolsclj

(shutdown-pools)
(shutdown-pools pool-name)

It shuts down, forcefully, all the circuit-breaker active pools. If you provide a pool-name it will shutdown only the specified one.

It shuts down, forcefully, all the circuit-breaker active pools.
If you provide a `pool-name` it will shutdown only the specified one.
sourceraw docstring

sleepclj

(sleep n)
(sleep b :+/- v)
(sleep :min a :max b)

It sleeps for at least n millis when not interrupted. If interrupted, it doesn't throw an exception.

It can be called in the following ways

  • (sleep n) It sleeps at least n milliseconds, if not interrupted (NOT RECOMMENDED)

  • (sleep b :+/- v) It sleeps random b millis +/- v%, for example: (sleep 3000 :+/- 0.5) means that it will sleep for 3s +/- 50%, therefore the actual interval can be between 1500 millis and 4500 millis (random uses uniform distribution)

  • (sleep :min l :max h) It sleeps for a random amount of time between min and :max

It sleeps for at least `n` millis when not interrupted.
If interrupted, it doesn't throw an exception.

It can be called in the following ways

- `(sleep n)`
  It sleeps at least `n` milliseconds, if not interrupted *(NOT RECOMMENDED)*

- `(sleep b :+/- v)`
  It sleeps random `b` millis `+/-` `v`%, for example:
  `(sleep 3000 :+/- 0.5)` means that it will sleep for
  `3s +/- 50%`, therefore the actual interval can be between
  `1500` millis and `4500` millis (random uses uniform distribution)

- `(sleep :min l :max h)`
  It sleeps for a random amount of time between `min` and `:max`

sourceraw docstring

sleeperclj

(sleeper :fix n)
(sleeper :random b :+/- v)
(sleeper :rand-cycle c :+/- v)
(sleeper :random-range :min l :max h)
(sleeper :random-exp-backoff :base b :+/- v)
(sleeper :random-exp-backoff :base b :+/- v :max m)

It returns a function (potentially stateful) which will sleep for a given amount of time each time it is called. All sleeps are randomized with the exception of the [:fix n] sleep (not recommended).

It can be called in the following ways

  • [:fix n] It sleeps at least n milliseconds (NOT RECOMMENDED)

  • [:random b :+/- v] It sleeps random b millis +/- v%, for example: [:random 3000 :+/- 0.5] means that it will sleep for 3s +/- 50%, therefore the actual interval can be between 1500 millis and 4500 millis (random uses uniform distribution)

  • [:random-range :min l :max h] It sleeps for a random amount of time between min and :max

It returns a function (potentially stateful) which will sleep for a
given amount of time each time it is called. All sleeps are
randomized with the exception of the `[:fix n]` sleep (not
recommended).

It can be called in the following ways

- `[:fix n]`
  It sleeps at least `n` milliseconds *(NOT RECOMMENDED)*

- `[:random b :+/- v]`
  It sleeps random `b` millis `+/-` `v`%, for example:
  `[:random 3000 :+/- 0.5]` means that it will sleep for
  `3s +/- 50%`, therefore the actual interval can be between
  `1500` millis and `4500` millis (random uses uniform distribution)

- `[:random-range :min l :max h]`
  It sleeps for a random amount of time between `min` and `:max`

sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close