text:
# safely
[![CircleCI](https://circleci.com/gh/BrunoBonacci/safely.svg?style=svg)](https://circleci.com/gh/BrunoBonacci/safely) [![Clojars Project](https://img.shields.io/clojars/v/com.brunobonacci/safely.svg)](https://clojars.org/com.brunobonacci/safely) ![CircleCi](https://img.shields.io/circleci/project/BrunoBonacci/safely.svg) ![last-commit](https://img.shields.io/github/last-commit/BrunoBonacci/safely.svg) [![cljdoc badge](https://cljdoc.org/badge/com.brunobonacci/safely)](https://cljdoc.org/d/com.brunobonacci/safely/CURRENT)

Safely is a Clojure's circuit-breaker library for handling retries in
an elegant declarative way.

The library offers out of the box:

  * declarative exception handling
  * declarative *circuit breaker* (in pure Clojure)
  * automatic policy-based retries (declarative)
  * randomized delays retries
  * attenuation of self-emergent behaviour in distributed systems
  * sleepless-mode for testing
  * automatic and customizable logging of errors
  * automatic tracking of errors rate/count in monitoring tools
  * automatic tracing compatible with OpenZipkin distributed tracing

## Usage

Add the dependency into your `project.clj`.

``` clojure
;; new version with μ/log tracking (event-based)
[com.brunobonacci/safely "0.7.0-alpha3"]

;; previous version TRACKit! tracking (metrics)
[com.brunobonacci/safely "0.5.0"]
```

  * Latest version: [![safely](https://img.shields.io/clojars/v/com.brunobonacci/safely.svg)](https://clojars.org/com.brunobonacci/safely)
  * Online [Documentation latest version](https://cljdoc.org/d/com.brunobonacci/safely/CURRENT).
  * Online [Documentation v0.5.0](https://cljdoc.org/d/com.brunobonacci/safely/0.5.0)

Require the namespace:

``` clojure
(ns foo.bar
  (:require [safely.core :refer [safely]]))
```

Then, make a call to a remote system:

``` clojure
;; wrap your critical calls
;; to external systems (api, db, etc)
;; into a `safely` block, and define
;; what to do in case of failures.

(safely
  (api-call "other-system")

  :on-error
  :max-retries 5
  :default   {:some :value})
```

This is a quick ref-card of all possible configurable options:

``` clojure

;;
;; all in one example
;;

(safely

 ;; code to execute
 (do (comment run something which can potentially blow))

 ;; exception handling
 :on-error

 ;; upon error return a default value
 :default "some value"

 ;; retry a number of times before
 ;; to give up or return the default value
 ;; use :forever for unlimited retries.
 :max-retries 5

 ;; between retries wait a fix amount of time (not recommended)
 :retry-delay [:fix 3000] ;; 3s in millis

 ;; or wait a uniform random range between :min and :max
 :retry-delay [:random-range :min 1000 :max 3000]

 ;; or wait a random amount of time with +/- a random variation
 :retry-delay [:random 3000 :+/- 0.35]

 ;; or wait an exponential amount of time with a random variation
 :retry-delay [:random-exp-backoff :base 3000 :+/- 0.50]
 :retry-delay [:random-exp-backoff :base 3000 :+/- 0.35 :max 25000]

 ;; or wait a given list of times with a random variation
 :retry-delay [:rand-cycle [50 100<PHONE_NUMBER> 2500] :+/- 0.50]

 ;; you can provide a predicate function which determine
 ;; which class of errors are retryable. Just write a
 ;; function which takes an exception and return something
 ;; truthy or falsey.
 :retryable-error? #(not (#{ArithmeticException NullPointerException} (type %)))

 ;; you can provide a predicate function which determine
 ;; if the output of the body should be considered as a failed response
 ;; this can be useful when using safely with APIs which have a return
 ;; status for errors instead of exceptions. Two good examples are HTTP
 ;; status codes and polling API, in which you wish to slow down the polling
 ;; when the result of the previous polling doesn't contain records.
 :failed? #(not (>= 200 (:status %) 299))

 ;; to activate the circuit breaker just give a name to the operation
 :circuit-breaker :operation-name

 ;; *PLEASE NOTE*: the following options are ONLY used in conjunction with
 ;; a circuit breaker

 ;; control the thread pool size for this operation
 :thread-pool-size  10

 ;; control the thread pool queue size for this operation
 :queue-size        5

 ;; the number of request's outcome to be sampled for analysis
 :sample-size       100

 ;; the number of milliseconds to wait before giving up
 ;; NOTE: it can be used only in conjunction with circuit-breaker
 :timeout           30000 ;; (millis, default no timeout)

 ;; What to do with the request when the timeout time is
 ;; elapsed. :never, :if-not-running or :always
 :cancel-on-timeout :always

 ;; stats are collected about the outcome of the operations
 ;; this parameter controls the number of 1-sec buckets
 ;; to control.
 :counters-buckets  10

 ;; the strategy used to trip the circuit open
 :circuit-breaker-strategy :failure-threshold

 ;; the threshold of failing requests after which the circuit trips
 ;; open. This is only used when
 ;; :circuit-breaker-strategy is :failure-threshold
 :failure-threshold 0.5

 ;; when the circuit breaker is tripped open, no requests will
 ;; be allowed for a given period.
 :grace-period      3000 ;; millis

 ;; the strategy to decide which requests to let through
 ;; for evaluation before closing the circuit again.
 :half-open-strategy :linear-ramp-up

 ;; the number of millis during which time an increasing number
 ;; of requests will be let through for evaluation purposes.
 :ramp-up-period    5000

 ;; General options.
 ;; customize your error message for logs
 :message "a custom error message"

 ;; set to false if you don't want to log errors
 :log-errors false

 ;; or choose the logging level
 :log-level :warn

 ;; to disable the stacktrace reporting in the logs
 :log-stacktrace false

 ;; whether to enable or disable tracking.
 ;; values: `:enabled` or `:disabled` (default: `:enabled`)
 :tracking :enabled

 ;; and track the execution time and outcome with the following action name
 ;; if not provided it will attempt to record the location (line + source file)
 :track-as ::action-name

 ;; 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.
 ;; for example:
 :tracking-tags [:batch-size 30 :user user-id]

 ;; 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.
 :tracking-capture (fn [r] {:http-status (:http-status r)})
 )

```

## Examples and Case studies

Here a collection of examples and case studies:

  * Use safely with AWS apis
    * [ETL-load job](./examples/etl-load/doc/etl-load-example.md) -
      See how the use of `safely` can greatly simplify your ETL jobs
      and make sure that you are fully utilising your database
      resources while being tolerant for transitory failures. It is
      also demonstrated that the exponential backoff exhibits great
      adaptive behaviours. The example is valid for Hadoop and Spark
      ETL jobs as well.

## Exception handling

The macro `safely` will run the given code and in case an exception
arises it will follow the policy described after the `:on-error`
keyword.

### Return default value

This is the simplest of the policies. In case of an exception with the
given code a default value will returned.

```Clojure
;; no error raised, so result is returned
(safely
 (/ 1 2)

 :on-error
 :default 1)
;;=> 1/2

;; an error is raised, but a default value is given
;; so the default value is returned
(safely
 ;; ArithmeticException Divide by zero
 (/ 1 0)

 :on-error
 :default 1)
;;=> 1
```

### Automatic retry

In some cases by retying a failed operation you can get a successful
outcome.  For example operations which involve network requests might
time out of fail for transitory network "glitches".  Typically, before
giving up, you want to retry some operations.

For example, let's assume you wish to retrieve the list active users
from a corporate RESTful webservice and you want to account for
transitory failures, you could retry the operation a number of times
before giving up.

The code could look like as follow:

```Clojure
;; Automatic retry
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3)
```

*In this case `:max-retries 3` means that there can be a maximum of 4
attempts* in total. Between each attempts the thread will be sleeping
for a random amount of time.  We will discuss retry delays later on.

If the first attempt succeed, then the result of the web request is
returned, however if an error arises then `safely` will retry until
one of the following conditions is reached: either a the operation
executes successfully, or the `:max-retries` is reached.

At the point the `:max-retries` is reached, if a `:default` value has
been provided then it will be returned, otherwise the exception will
be thrown up the stack.

```Clojure
;; Automatic retry with default value
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :default {:accounts [] :status "BUSY"})
```

In the previous case the HTTP GET operation may fail and it will be
automatically retried for a maximum of 3 times, after which, the
default value of `{:accounts [] :status "BUSY"}` is returned.

If the `:default` clause it is omitted the a
`clojure.lang.ExceptionInfo` will the thrown with the details of the
number of attempts and the original cause.

### Retry delays and randomization

#### Self-emergent Behaviour

In large distributed systems failures can produce strange behaviour
due to the fact that all participant act in the exact same way.
Consider the example of a service failure where all other services
which use the former detect the failure and decide to retry after the
exact same amount of time. When the system comes back to life it will
be flooded with retry requests from all the other services at the same
time. If the number of client service is big enough can cause the
service which is already struggling to die and reboot in a continuous
cycle.

> "Emergent behavior is that which cannot be predicted through analysis
> at any level simpler than that of the system as a whole. Emergent
> behavior, by definition, is what’s left after everything else has been
> explained" (Dyson and George 1997).

> "Emergent behavior is also been defined as the action of simple rules
> combining to produce complex results" (Rollings and Adams 2003)

In this paper
[Emergent Behavior in Systems of Systems]( http://faculty.nps.edu/thuynh/Conference%20Proceedings%20Papers/Paper_14_Emergent%20Behavior%20in%20Systems%20of%20Systems.pdf)
you can see more examples of emergent behaviour.

#### Retry policies

`safely` implements several randomization strategies to minimize
the appearance of these large scale issues.

All delay strategies are randomized by default, here is a list of those
we currently support.

The default configuration is: `[:random-exp-backoff :base 300 :+/- 0.50 :max 60000]`

* `:random-range` (min/max) - it define a random range between a fixed boundary
* `:random` (amount +/- random percentage) - It define an amount and
  percentage of variation (both sides + or -) from that base amount
* `:random-exp-backoff` - (**default strategy**) it define an amount
  of time between each attempt which grows exponentially at every
  subsequent attempt and it is randomized with a custom +/-
  percentage. Optionally you can specify a maximum amount of time
  beyond which it won't grow any more.
* `:rand-cycle` - if none of the above strategies suits your case you
  can specify your own list of delays between each attempts and a
  randomization factor. If the number of attempts goes beyond the
  listed values it will start from the first one again in a continuous
  cycle.
* `:fix` for special cases you can specify a fix amount of time
  between retry, however i do not recommend the use of this strategy.

Now we will show how each strategy works with code samples.

#### :fix

In this example `safely` will retry for a maximum of 3 times with a
delay 3 seconds (3000 milliseconds) exacatly. This strategy is
strongly discouraged in order to minimize self emergent behaviour.

```Clojure
;; Automatic retry with fix interval (NOT RECOMMENDED)
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:fix 3000])
```

#### :random-range

In this example `safely` will retry for a maximum of 3 times with a
delay of minimum 2 seconds (2000 milliseconds) and a maximum of 5
seconds (5000 milliseconds).

```Clojure
;; Automatic retry with random-range
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random-range :min 2000 :max 5000])
```

#### :random

In this example `safely` will retry for a maximum of 3 times with a
delay 3 seconds (3000 milliseconds) and plus or minus an amount **up
to** 50% of the base amount. This means that the waiting time could be
effectively anything between 1500 millis (3000 - 50%) and 4500 millis
(3000 + 50%).

```Clojure
;; Automatic retry with random-range
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random 3000 :+/- 0.50])
```

#### :random-exp-backoff

In this example `safely` will retry for a maximum of 3 times with a
exponential backoff delay of 3 seconds (3000 milliseconds) and plus or
minus random 50% of the base amount. This means that the first retry
will be ~3 sec (+/- random variation), the second retry will ~9 sec
(+/- random variation) etc.

```Clojure
;; Automatic retry with random-range
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random-exp-backoff :base  3000 :+/- 0.50])
```

**The Math gotchas:** The exponential backoff typically follows this
formula:

    delay = base-delay ^ retry-number +/- random-variation

for a typical exponential back off for 3 sec would be:

    retry:     1     2     3     4 ...
    formula:  3^1   3^2   3^3   3^4
    delay:     3     9    27     81 sec

however the base amount is specified in milliseconds (not in seconds)
which mathematically would be (this is not how `safely` implements the
backoff):

    retry:     1         2          3         4 ...
    formula: 3000^1   3000^2      3^3       3^4
    delay:   3000     9000000    27+E9     81+E12
              3s     2.5 hours  +20 years
             THIS IS NOT HOW SAFELY OPERATES

Which means the second retry will be after *2.5 hours* and the third
retry will be after *20 years*. I'm sure that none of your apps
wants to wait 20 years before retrying, therefore `safely` despite
requiring the time in milliseconds will try to adapt the exponential
backoff base to scale of the number.

So for example for a given base you have the number of
milliseconds of each subsequent retry:

| Base | Retry 1 | Retry 2 | Retry 3 | Retry 4 | Retry 5 |
|-----:|--------:|--------:|--------:|--------:|--------:|
|   50 |      50 |     250 |    1250 |    6250 |   31250 |
|  200 |     200 |     400 |     800 |    1600 |    3200 |
| 2000 |    2000 |    4000 |    8000 |   16000 |   32000 |
| 3000 |    3000 |    9000 |   27000 |   81000 |  243000 |

The algorithm takes base and it compute the size of base (log10 base)
and it strips down the least relevant digits before the power is
applied.  This ensures that the exponential back off maintains
practical timing while still increasing the delay of every retry.

The following formula explains better how it works :

![formula](/doc/images/retry-formula.png)

If you wish to check the sequence for a given base you can try on the
REPL as follow:

```Clojure
(require 'safely.core)
(take 10 (#'safely.core/exponential-seq 2000))
;;=> (2000 4000 8000 16000 32000 64000<PHONE_NUMBER>00<PHONE_NUMBER>000)
```

**The randomization is applied after the exponential value has been
  calculated**

#### :random-exp-backoff (with :max)

Additionally you can specify a maximum amount of time which beyond
which you want to wait for a similar amount of time.

```Clojure
;; Automatic retry with random-range with a max delay
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random-exp-backoff :base  3000 :+/- 0.50 :max 240000])
```

The above example set a maximum delay of **4 minutes** (240000 millis)
beyond which time `safely` won't backoff exponentially any more, but
it will remain constant.

Example for the effect of `:max 240000`

```Clojure
(require 'safely.core)
;; without :max
(take 10 (#'safely.core/exponential-seq 3000))
;;=> (3000 9000 27000 81000<PHONE_NUMBER>00 2187000 6561000 19683000 59049000)

;; with :max 240000
(take 10 (#'safely.core/exponential-seq 3000 240000))
;;=> (3000 9000 27000 81000<PHONE_NUMBER>00<PHONE_NUMBER>00<PHONE_NUMBER>00)
```

#### :rand-cycle

If you don't like the exponential backoff, then you can specify a
sequence of expected delays between each retry. `safely` will use these
times (in milliseconds) and add randomization to compute the amount of
delay between each retry. Once last delay in the sequence is reached
`safely` will cycle back to the first number and repeat the sequence.

```Clojure
;; Automatic retry with random list of delays
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 6
  :retry-delay [:rand-cycle [1000 3000 5000 10000] :+/- 0.50])
```

In the above example I've specified the desired waiting time (with
variation) of **1s, 3s, 5s and 10s**, I've also specified that I would
like `safely` to retry **6 times**, but only 4 wait times were
specified. Safely will cycle back from the beginning of the sequence
producing effective waiting times of:

    retry:     1     2     3     4      5     6
    delay:   1000  3000  5000  10000  1000  3000
             |---------------------|  |---------...
       cycling back to the beginning of the sequence

In this way you can specify your custom values which better suits
your particular situation.

### Errors logging

One common mistake is to have empty `catch` block. The exception in this case
it is swallowed by the program without leaving any trace. There are very few
occasion when this is a good idea, in most of the cases it is recommended to
at least log the exception in a logging system.
`safely` by default logs the exception with `timbre`. There are a few configurable
option which you can leverage to make message more suitable for your situation.

We have:

* `:message` to customize the log message and make it more meaningful
  with information which pertain the action you were trying to
  achieve.
* `:log-level` the level to use while logging the exception. The
  default value is `:warn`, other possible values are: `:trace`,
  `:debug`, `:info`, `:warn`, `:error` and `:fatal`
* `:log-errors` (`true`|`false`) whether or not the error must be
  logged. If you don't want to log exceptions in a particular block
  you can disable it with: `:log-errors false`
* `:log-stacktrace` (`true`|`false`) whether to report the full
  stacktrace of the exception or omit it completely. (default `true`)
* `:log-ns "logger.name"` To specify a logger name. Typically the
  name of a namespace. When using the macro it defaults to the current
  namespace, when using the function version it defaults to `safely.log`

For example this log the exception with the given message and a log
level of `:info`.

```Clojure
;; Customize logging
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :message "Error while fetching active users"
  :log-level :info)
```

In this case we disable the error logging for the given block.

```Clojure
;; Disable logging
(safely
  (Thread/sleep 3000)
  :on-error
  :log-errors false)
```

### Automatic tracking (monitoring)

If you have (and you should) a monitoring system which track application
metrics as well then you can track automatically how many times a
particular section protected by safely is running into errors.

Tracking is enabled by default, but if you wish to disable it, set:

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

If you wan to track a particular section, all you need to do is to
give a name to the section you are protecting with safely with:

* `: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
  put `:track-as nil` the tracking event won't be collected, but
  the tracking context will be created..

For example:

```Clojure
;; Automatic retry with random-range
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random-range :min 2000 :max 5000]
  :track-as ::fetch-active
  :circuit-breaker :fetch-active-users)
```

This will track the call events providing a number of interesting
information about this single block and publish them to a variety of
monitoring systems.

* `: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)})`

For more information you can see the [tracking](./doc/tracking.md)
page.

With [***μ/trace***](https://github.com/BrunoBonacci/mulog#%CE%BCtrace)
your `safely` expressions turn into traces which you can visualise
with [OpenZipkin](https://zipkin.io/) compatible tracers.

Here is one example:

![mulog tracing](./doc/images/mulog-tracing.png)

### Circuit breaker.

The circuit breaker functionality (introduced in v0.5.0) was
popularised by [M. T. Nygard's book "Release
It!"](https://books.google.co.uk/books?id=md4uNwAACAAJ) and
[2nd ed.](https://books.google.co.uk/books?id=Ug9QDwAAQBAJ).
There are already a good amount of open-source libraries which offer
quite good implementation of circuit-breakers as defined by
Nygard. The most popular it is
[Hystrix](https://github.com/Netflix/Hystrix) from Netflix.  However,
Hystrix over the years became unnecessarily a huge library.  `safely`
offers an implementation of the same ideas in a much simplified way
and 100% Clojure (for JVM).

If you want to know more about the general idea behind the circuit
breaker I would recommend the book "Release It!" mentioned above. Here
I'm going to describe how `safely` implementation works.

Internally the circuit breaker is a state machine which looks like
this:

![circuit breaker state machine](/doc/images/circuit-breaker-sm.png)

The state machine is initiated with the `:closed` state. Like an
electrical circuit a _closed_ circuit it is a working circuit in which
the current can flow through.

#### **`:closed` state**

In this state the circuit breaker is allowing to pass all the
requests. So when a new request is issued, the circuit breaker will
retrieve the dedicated thread pool associated with this request type
and enqueue the new request. Once enqueued an available thread will
pick the request and process it. When the request is completed then
the circuit breaker will update its internal state capturing the
outcome of each request. In this case one of the following things can
happen:

  - **the request is successful**, then the result from the processing
    thread is returned to the caller.
  - **the request processing fails with an error**, in this case the
    error is propagated back to the caller and further retries could
    be made depending whether they are configured and within the
    limit. If the limit of retries in `:max-retries` is reached then the
    `:default` value is returned when provided or the error itself.
  - **the request times out**, if the request has configured
    `:timeout` and the processing isn't completed within this time, an
    exception is raised and it follows the same path and the
    processing error.
  - **all threads and busy and no more requests can be enqueued**, in
    this case the request is rejected (`:queue-full`) and the same
    error handling path or retries is used.  The number of threads and
    the queue size are configurable parameters.  More on how to size
    them properly later.

For any of the above outcomes the circuit breaker state machine updates
a counter. Only counters for the last few seconds are kept and they are
used by the state evaluation function to determine whether the circuit breaker
should be tripped and move to the next state.

Currently the following strategies are available to trip the circuit breaker:

  - **:failure-threshold** which it looks at the counters and trips
    the circuit open when a configurable threshold of failing requests
    is reached. It will wait until at least 3 requests have been
    processed before verifying the threshold. Very simple and
    effective.

#### **`:open` state**

If the state evaluation function decides to trip the circuit off
because too many errors occurred, then the circuit breaker state
machine goes into the `:open` state. In this state all incoming
requests are rejected immediately with a `:circuit-open` error and the
standard error path with retries is followed.

This is useful to immediately reduce the load into the target system.
The circuit stays open for a few seconds (according to
`:grace-period`) and then the circuit automatically transitions to the
`:half-open` state.

#### **`:half-open` state**

The purpose of this state is to assess whether the target system is
back to normal before closing the circuit back and allow all the
requests. So for this purpose the circuit breaker allows only a few
requests to pass and it checks their outcome. If the system keep
failing then the circuit goes back to the `:open` state, if the
requests and now successful and the issue seems to be resolved then
the circuit goes back to the `:closed` state.
The same evaluation function used to trip the circuit open is used
to evaluate whether now is back to normal.

During the `:half-open` state, only a part of the incoming requests
will be allowed. The number of the requests allowed depends on the
`:half-open-strategy`.

These are the currently supported strategies:

  - **`:linear-ramp-up`**, it will ramp up the number of requests
  allowed in the circuit breaker over time. The length of time is
  configurable via `:ramp-up-period`. The system will go back to
  closed only after the `:ramp-up-period` is elapsed, however if it
  detects failures during the ramp up it will preemptively open the
  circuit again.

#### How to use the circuit-breaker

To activate the circuit breaker function just add the `:circuit-breaker`
option if your `safely` options:

```Clojure
;; activating circuit breaker
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  ;; give a name to the circuit-breaker
  :circuit-breaker :fetch-active-users
  ;; optionally set a timeout for this operation (millis)
  :timeout 30000)
```

That's it!. `safely` in the background will create a thread pool named
`:fetch-active-users` which will be in charge of processing the
requests. You can use the circuit breaker in conjunction with all
other safely options such as retry strategies, log and tracing.

_**NOTE**: for every unique value passed to `:circuit-breaker` a
number of resources need to be created in the system, namely the
thread-pool and the circuit-breaker state machine. Therefore you must
ensure that the values passed to the `:circuit-breaker` options are
**not randomly generated or high cardinality** to avoid the risk of
running out of memory in your system. Best practice is to name the
circuit breaker after the operation that it is trying to accomplish._

#### Circuit breaker functions

##### `shutdown-pools`

For every named circuit breaker, `safely` will create its own
dedicated thread pool. If you wish to shutdown the pool
programmatically then you can call the `shutdown-pools` function
with a specific circuit breaker name or without parameters
to shut all of them down.

##### `circuit-breaker-info`

If you want to access the info stored in the state machine
for monitoring purposes then you can use the `circuit-breaker-info`
function with a circuit breaker name for the state regarding the
specific circuit breaker or without parameters for all.

#### How to size the thread pool

You might think that a thread pool of 10 is very small for your
system, and you might be tempted to increase this number by one order
of magnitude.  Although some times this is the correct thing to do,
most of the time it won't be. The defaults are already set for large
volume systems so most of you won't need to change the size of the
thread pool and/or the queue length.  However if you think you should
change these values for your system I would recommend to use the
[Litlle's Law](http://web.mit.edu/~sgraves/www/papers/Little's%20Law-Published.pdf)
(from Queueing Theory) to choose the correct size.

The _Little's Law_ says that the long term average number of items `L`
in your system is equal to the average arrival rate `λ` multiplied by
the long term average time `W` required to process that item, therefore:

![Little's Law](/doc/images/LittleLaw.png)

The interesting property about the _Little's Law_ is that it applies
to the whole system as well as its individual parts.  This means that
this law will apply to your system as a whole, meaning all the
instances of your system in the cluster, as well as the individual
instances. Moreover, if your single instance has two possible paths
with two different probabilities, it will apply to these sub-parts as
well with the parameters adjusted accordingly.

For example if you have a system which processes 5000 requests/second
as a whole, and you have 15 instances to serve these requests,
and each requests takes on average 25 milliseconds, then we can reason
as follow:

  * `λ = 5000 rq/s`
  * `W = 25 millis -> 0.025s`
  * then we can deduce that `L` for the whole system is going to be:
  * `L = λW -> 5000 rq/s * 0.025 s -> L = 125`
  * So it means that the whole system will have an average of `125`
    concurrent requests when processing `5000 rq/s`.
  * Since every instance follow the Little's law as well and
    since all the instances have typically the same probability
    to get a request (via a load balancer), then it is safe
    to assume that every instance will have the same share of traffic.
    Since we ha *15 instances* then we can say that:
  * `Li = L / 15 -> 125 / 15 -> Li = 8.34` where `Li` is the load of a
    single instance.

As you can see although your system as a whole processes a lot of
requests per seconds, the individual instance _concurrent load `Li`_
it will be within the range of the thread pool. If we size the thread
pool a bit larger to cope with requests bursts and we add a small
queue typically 30%-50% of the thread pool size we can ensure that
occasional hiccups and bursts of requests are handled properly without
causing the circuit breaker to trip over.

I hope this small guide helps you to correctly size your system.
Anyway, always use measurements (tracking, monitoring) to compute
the right size and verify you changes according to your assumptions
to see if the change had the effect you hoped.

### Macro vs function

`safely` it's a Clojure macro which wraps your code with a try/catch
and offers a elegant declarative approach to the error
management. However in many cases macro can't be used easily for this
reason we provide a function as well.

Everything you can do with the macro `safely` you can do with the
function `safely-fn` which takes a **thunk** (function with zero
arguments and the same options with `safely` takes after the
`:on-error` clause.

So for example this is the use of the macro you have seen so far:

```Clojure
;; Automatic retry with random-range
(safely
  (http/get "http://user.service.local/users?active=true")
  :on-error
  :max-retries 3
  :retry-delay [:random-range :min 2000 :max 5000])
```

This is the same example **but with the `safely-fn` instead**:

```Clojure
;; Automatic retry with random-range
(safely-fn
  (fn []
    (http/get "http://user.service.local/users?active=true"))

  :max-retries 3
  :retry-delay [:random-range :min 2000 :max 5000])
```

_Note the use of the **thunk** to wrap the code and the absence of the
 `:on-error` keyword._

### Testing and the `sleepless-mode`

If you are writing automated test but you don't want to wait then
you can enable the **sleepless-mode** in order to skip the waiting
times of the retry for example:

This might wait up to 40s before returning "".

```Clojure
;; this might wait up to 40s before returning ""
(safely
  (slurp "/not/existing/file")
  :on-error
  :max-retries 5
  :default "")
```

This one does the same number of retries but doesn't sleep and it
returns immediately (same code path, but no sleep).

```Clojure
;; This one does the same number of retries but doesn't sleep
(binding [safely.core/*sleepless-mode* true]
  (safely
    (slurp "/not/existing/file")
    :on-error
    :max-retries 5
    :default ""))
```

## License

Copyright © 2015-2020 Bruno Bonacci

Distributed under the Apache License v 2.0 (http://www.apache.org/licenses/LICENSE-2.0)

repository: BrunoBonacci/safely

repo_name: BrunoBonacci/safely


text:
Pattern: Use of `time` with compound command

Issue: -

## Description

`time` is only defined for Simple Commands [by POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/time.html). Timing loops, command groups and similar is not.

Example of **incorrect** code:

```sh
time for i in *.bmp; do convert "$i" "$i.png"; done
```

Example of **correct** code:

```sh
time sh -c 'for i in *.bmp; do convert "$i" "$i.png"; done'
```
## Exceptions

None. If you use a shell that supports this (e.g. bash, ksh), specify this shell in the shebang.

## Further Reading

* [ShellCheck - SC2177](https://github.com/koalaman/shellcheck/wiki/SC2177)

license: MIT

repository: Adroiti/docs-for-code-review-tools

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: Adroiti/docs-for-code-review-tools


text:
# Handling conflicts

## Using the command line

1. Create a new feature `branch`.
    ```
    git checkout -b feature/exercise4
    ```

2. Make some changes to the code. This time, make some changes to the contents of an existing paragraph.
    \-

3.  "Simulate" that someone else has made conflicting changes and pushed them to the `master` branch while we were working on our new feature.
    - Make new changes to the same paragraph that you changed in 2.
        \-
    - Commit them in the `master` branch.
        ```
        git add --update
        git commit -m"Someone else made changes"
        ```

6. `merge` your new branch into `master`.
    ```
    git merge feature/exercise4
    ```

7. Oh no! Conflicts. Let's resolve them.
    ## Using the command line
    I recommend installing a third party tool to resolve conflicts, for example [kdiff3](http://kdiff3.sourceforge.net/) or [p4merge](https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge) and then configure your git GUI or git from the command line to use that tool for diffs and merges.

    After you have resolved the conflicts you have to commit the merge:
    ```
    git commit -m"Merge feature/exercise4 into master"
    ```

    ## Using visual studio
    When there are merge conflicts they will show up under the Branches view in the Teams Explorer. Click on conflicts to view the conflicts.

    Click on the file you wish to handle conflicts for and press the Merge button to get to the merge view:

    In the merge view select which change to keep (left or right) and select with the checkbox next to the changed line of code. Then click Accept Merge in the top of the merge view.
    In the Team Explorer you can then choose to commit the merge.

8. `push` your changes.
    ```
    git push
    ```

9. Go to your Azure DevOps repository and verify that your changes have been pushed to the `master` branch.
    \-

repository: viktorvan/introduction-to-git

repo_name: viktorvan/introduction-to-git


text:
Reactfolio

A CLI based Portfolio builder that only asks you to enter your details in a json file and builds a minimilastic react portfolio based on it. Super simple to use and a great way to show off your cool projects !

#### Checkout the [demo](https://youtu.be/O7GDJ7d8MF0)

## Installation

Clone this repo and install dependencies

```shell
git clone https://github.com/..
cd ReactFolio
npm install
```

Modify the sample.json based on your profile. For [reference.](https://github.com/AK5123/ReactFolio/blob/master/sample.json)

To host your portfolio in surge,

```shell
node index.js sample.json
```

#### Checkout my [Portfolio](https://kandavel.surge.sh) built using ReactFolio.

repository: SocioProphet/ReactFolio

repo_name: SocioProphet/ReactFolio


text:
# flagconfig

A very simple library for specifying parameters and their default values and
having them be read in from either the command-line or a configuration file.

# Installation

Goatfile:
```json
{
    "loc":"github.com/mediocregopher/flagconfig"
}
```

Standard
```bash
go get github.com/mediocregopher/flagconfig
```

# Usage

See the [example](/example) for basic usage.

repository: colekowalski/flagconfig

repo_name: colekowalski/flagconfig


text:
# appsetings.Development.json does not load properly

[Issue Page](https://github.com/aspnet/AspNetCore/issues/11709)

## contents

I'm afraid of being that appsettings.Development.json does not load properly.

When I debug my aspnetcore application I found that a variable was set unexpectedly, which the variable comming from appsettings.json, not appsetings.Development.json.

### Environment

| name | value  |
|---|---|
| OS  | Ubuntu Budgie 19.04  |
| dotnet | 2.2.204 |
| DevTool | Visual Studio Code |

### Details

In my appsetting.json;

``` JSON
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "Jwt": {
    "Key" : "devKey_appsettng_noenv",
    "Issuer": "http://localhost:5000",
    "ExpireMinutes": 30
},
"ConnectionStrings": {
  },
  "AllowedHosts": "*"
}
```

and my appsetting.Development.json;

``` JSON
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Jwt": {
      "Key" : "devKey12345678901234567890",
      "Issuer": "http://localhost:5000",
      "ExpireMinutes": 30
    },
    "ConnectionStrings": {
    }
    }
}
```

In my aspnetcore application, codes loading appseting.*.json are below(generated by dotnet command, not changed);

``` C#
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
```

and Startup class is below;

``` C#
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            this.Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<AppSettings>(this.Configuration);

            // OTHER CONFIGURATIONS......
        }
    }
```

In a controller class, I load configurations using POCO AppSettings class.

``` C#
    public class LoginController : ControllerBase
    {
        private readonly AppSettings _config ;

        public LoginController(IOptions<AppSettings> configuration)
        {
            this._config = configuration.Value;
        }

        // OTHER METHODS......
    }
```

When I start debugging with Visual Studio Code , which launching configuration has ``"ASPNETCORE_ENVIRONMENT": "Development"`` in the env section ,I found the property LoginController._config.Jwt.Key has value ``devKey_appsettng_noenv``, not ``devKey12345678901234567890``.

gha_language: C#

gha_license_id: MIT


text:
---
layout: post
title: Photos
lang: en
description: "Photos from the test ride"
headline: "Photos from the first test ride"
categories: photos
tags:
  - partners
  - trike
comments: true
mathjax: null
featured: false
published: true
---

Finally received the trike on Thursday, assembled it in the evening and made some 30 kms of test rounds on Cannes bike ring
on Friday evening. Today I rode the first 70 km on road, including some moderate hills and took some photos.

I have not yet found the optimal
seat adjustments, and some aerodynamic tweaking needs to be done, but one thing is sure: this thing is certainly faster than
anything I have ridden before. I'm really excited!

Anyways, the photos are below. Hope you like them.

![Photo 1](/images/2016May/IMG_7634.jpg)

![Photo 2](/images/2016May/IMG_7632.jpg)

![Photo 3](/images/2016May/IMG_0113.jpg)

![Photo 4](/images/2016May/IMG_0120.jpg)

![Photo 5](/images/2016May/IMG_0114.jpg)

![Photo 6](/images/2016May/IMG_0122.jpg)

path: /en/_posts/2016-05-14- firstphotos.md

filename: 2016-05-14- firstphotos.md


text:
## 0.2.3 (October 15, 2022)
  - Added File Handler

## 0.2.2 (October 15, 2022)
  - Fixed request log nil error

## 0.2.1 (September 22, 2022)
  - Changed go version to v1.19

## 0.2.0 (September 21, 2022)
  - Upgraded packages

## 0.1.27 (May 26, 2019)
  - Added html handlers
  - Added static file handlers
  - Added ability to set status codes

## 0.1.26 (April 13, 2019)
  - Added Coverage badge to README.md

## 0.1.25 (April 13, 2019)
  - Fixed README.md

## 0.1.24 (April 13, 2019)
  - Fixed travis.yml

## 0.1.23 (April 13, 2019)
  - Fixed travis.yml

## 0.1.22 (April 13, 2019)
  - Fixed travis.yml

## 0.1.21 (April 13, 2019)
  - Fixed travis.yml

## 0.1.20 (April 13, 2019)
  - Fixed travis.yml

## 0.1.19 (April 13, 2019)
  - Fixed travis.yml

## 0.1.18 (April 13, 2019)
  - Fixed travis.yml

## 0.1.17 (April 13, 2019)
  - Fixed travis.yml

## 0.1.16 (April 13, 2019)
  - Fixed travis.yml

## 0.1.15 (April 13, 2019)
  - Fixed travis.yml

## 0.1.14 (April 13, 2019)
  - Updated README.md
  - Fixed travis.yml

## 0.1.13 (April 12, 2019)
  - Fixed bugsnag error reporting

## 0.1.12 (April 12, 2019)
  - Fixed segment reporting
  - Middleware Error Reporting will send errors to external such as bugsnag

## 0.1.11 (April 10, 2019)
  - Fixed undefined properties

## 0.1.10 (April 10, 2019)
  - Fixed import issues_2

## 0.1.9 (April 10, 2019)
  - Generic metric collector and error reporting

## 0.1.8 (April 09, 2019)
  - Fixed import issues

## 0.1.7 (April 09, 2019)
  - Made Metric Collectore more generic

## 0.1.6 (April 06, 2019)
  - Updated dependencies

## 0.1.5 (April 06, 2019)
  - Fixed import issues

## 0.1.4 (April 06, 2019)
  - HTTP Writer and response can be accessed by the handlers

## 0.1.3 (January 13, 2019)
  - Fixed Middleware imports.

## 0.1.2 (January 13, 2019)

## 0.1.1 (January 13, 2019)
  - Fixed ReadMe file.

## 0.1.0 (January 12, 2019)
  - Wrapper for httpRouter
  - Added middleware support for newrelic
  - Added middleware support for bugsnag

repository: illuminasy/gorouter

repo_name: illuminasy/gorouter


text:
# What's new

## [0.7.0]

- Added invertedHex to contrast with background colors of statusbar, titlebar and activity bar - [PR #16](https://github.com/oreporan/color-tabs-vscode/pull/16)

## [0.6.0]

- ColorTabs now changes the color of your status bar (set to true by default) - [PR #10](https://github.com/oreporan/color-tabs-vscode/pull/10).
set `colorTabs.statusBarBackground` to `true` in your workspace settings to get this new feature.
Example (with `mobile` label):
![Title label](./docs/color-tabs-6.0.png)

- ColorTabs can now change the color of your activity bar (Left side bar) - [PR #10](https://github.com/oreporan/color-tabs-vscode/pull/10).
set `colorTabs.activityBarBackground` to `true` in your workspace settings to get this new feature.
Example (with `mobile` label):
![Title label](./docs/color-tabs-5.0.png)

## [0.5.0]

- ColorTabs can now add a label to your title background as well - [PR #4](https://github.com/oreporan/color-tabs-vscode/pull/4).
set `colorTabs.titleLabel` to `true` in your workspace settings to get this new feature.
Example (with `mobile` label):
![Title label](./docs/color-tabs-5.0.png)

## [0.4.4]

- ColorTabs can now color your title background as well - [PR #2](https://github.com/oreporan/color-tabs-vscode/pull/2).
set `colorTabs.titleBackground` to `true` in your workspace settings to get this new feature.
Example:
![Title background](./docs/color-tabs-4.4.gif)

repository: oreporan/color-tabs-vscode

gha_language: TypeScript

repo_name: oreporan/color-tabs-vscode


text:
# Ember-calendly [![Build Status](https://travis-ci.org/mike-north/ember-calendly.svg?branch=master)](https://travis-ci.org/mike-north/ember-calendly) [![Ember Observer Score](https://emberobserver.com/badges/ember-calendly.svg)](https://emberobserver.com/addons/ember-calendly) [![npm version](https://badge.fury.io/js/ember-calendly.svg)](https://badge.fury.io/js/ember-calendly) [![Code Climate](https://codeclimate.com/github/mike-north/ember-calendly/badges/gpa.svg)](https://codeclimate.com/github/mike-north/ember-calendly)

[![Greenkeeper badge](https://badges.greenkeeper.io/mike-north/ember-calendly.svg)](https://greenkeeper.io/)

Easy [Calendly](https://calendly.com/) integration for Ember.js apps.

**[FASTBOOT](http://ember-fastboot.com) COMPATIBLE**

## Use

```
ember install ember-calendly
```

Then you have three options for embedding calendly.

### Inline

```hbs
{{calendly-inline
  url='https://calendly.com/mnorth'
  style=(hash
    min-width='320px'
    height='580px')}}
```

### Popup Widget

```hbs
{{calendly-popup-widget
  url='https://calendly.com/mnorth'}}
```

### Popup Text

```hbs
{{calendly-popup-text
  url='https://calendly.com/mnorth'}}
```

## Other stuff

You may also import Calendly as an ES6 module

```js
import Calendly from 'calendly';

Calendly.closePopupWidget();
```

## Running

* `ember server`
* Visit your app at http://localhost:4200.

## Running Tests

* `npm test` (Runs `ember try:testall` to test your addon against multiple Ember versions)
* `ember test`
* `ember test --server`

## Building

* `ember build`

For more information on using ember-cli, visit [http://ember-cli.com/](http://ember-cli.com/).

© Levanto Financial Inc, All Rights Reserved

repository: AmilKey/ember-calendly

repo_name: AmilKey/ember-calendly


text:
---
layout: page
title: "Sources"
description: "Business components responsible for providing model data."
order: 4
disqus: 1
---

In Elements, sources have the responsibility of providing model data. They can be extremely simple and extremely complex
if needed, through a [dependency mechanism](coordination).

For now, let's look at the main callbacks and APIs:

|Callback / API|Description|
|--------------|-----------|
|`onPageOpened(page: Page, dependencies: List<Element<*>>)`|The given page was opened. You are required to provide results using one of the `postResult` methods. If the source declared some dependencies, this method will be called once the dependencies are resolved, and will be passed a list of the elements provided by the dependencies.|
|`onPageChanged(page: Page, dependencies: List<Element<*>>)`|The given page was changed. This is only called if the source declares some dependencies. At this point it can process the list of dependencies elements and, if needed, update its results, as above, using one of the `postResult` methods.|
|`postResult(page: Page, data: Collection<T>)`|Posts results for the given page. Can be called at any time, from any thread.|
|`postResult(page: Page, error: Exception)`|Posts an error for the given page. This means we have no results for this page.|
|`postResult(page: Page, liveData: LiveData<List<T>>)`|Binds this page to the given `LiveData` object. This means that anytime this `LiveData` provides results, we will post them to the given page.|

When posting results, the list of `T` data is converted to a list of `Element<T>` object.
The source can declare the element type for each `T` data in the `getElementType(T)` callback.

### State restoration

Sources hold strong references to pages and model data. This has a pleasant consequence:

> If you hold sources in your architecture `ViewModel`, and pass them to a new adapter, the adapter
> will restore pages and data seamlessly during configuration changes.

The approach should be the following:

```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    Adapter.builder(this)
        .addSource(viewModel.contactsSource)
        .addPresenter(presenter)
        .into(recyclerView)
}
```

### Overriding results

Source subclasses have the opportunity to **change the results that were posted**. See, for example, this code
that replaces empty lists with a *this list is empty* Element:

```kotlin
override fun onPostResult(page: Page, result: Result<T>): List<Element<T>> {
    if (result.error != null) {
        return listOf(createEmptyElement(ELEMENT_TYPE_ERROR, result.error))
    } else if (result.values.isEmpty()) {
        return listOf(createEmptyElement(ELEMENT_TYPE_EMPTY))
    } else {
        return result.values
    }
}
```

At this point, you will need a presenter for the `ELEMENT_TYPE_ERROR` and `ELEMENT_TYPE_EMPTY` types.
In fact, this is already available in the [extensions](extensions) provided by the library.

### DiffUtils

Like the Google's Paging library, the adapter will use [`DiffUtil`](https://developer.android.com/reference/android/support/v7/util/DiffUtil)
to compute what changed and call the appropriate `notify*` methods on the adapter.

The computation is performed

- in a background thread
- at the page level. This means that it will deal with less elements and be fast
- anytime something in the page has changed

For this to work better, please provide an implementation of the equality callbacks:

```kotlin
class ContactsSource : Source<Contact> {

    // Whether two items point to the same model entity (that might be changed).
    override fun areItemsTheSame(first: Contact, second: Contact): Boolean {
        return first.id() == second.id()
    }

    // Used to detect whether the model entity has changed. Will call notifyItemChanged().
    // Defaults to full equality.
    override fun areContentsTheSame(first: Contact, second: Contact): Boolean {
        return first == second
    }
}
```

repository: ramipa/Elements

repo_name: ramipa/Elements


text:
# EnGarde

EnGarde allows you to validate arguments using a fluent interface, for example:

```csharp
Ensure.That(() => value).Not.IsNull().And.StartsWith("En");
```

## Where can I get it?

Open the Visual Studio Package Manager Console and run the following command:

``
Install-Package EnGarde -pre
``


text:
# FLoC SimHash

This Python package provides hashing algorithms for computing cohort ids of users based on their browsing history.
As such, it may be used to compute cohort ids of users following Google's **Federated Learning of Cohorts** (FLoC) proposal.

The FLoC proposal is an important part of [The Privacy Sandbox](https://www.chromium.org/Home/chromium-privacy/privacy-sandbox), which is Google's replacement for third-party cookies.
FLoC will enable interest-based advertising, thus preserving an important source of monetization for today's web.

The main idea, as outlined in the [FLoC whitepaper](https://raw.githubusercontent.com/google/ads-privacy/master/proposals/FLoC/FLOC-Whitepaper-Google.pdf), is to replace user cookie ids, which enable user-targeting across multiple sites, by _cohort ids_.
A cohort would consist of a set of users sharing similar browsing behaviour.
By targeting a given cohort, advertisers can ensure that relevant ads are shown while user privacy is preserved by a _hiding in the pack_ mechanism.

The FLoC whitepaper mentions several mechanisms to map users to cohorts, with varying amounts of centralized information.
The algorithms [currently](https://blog.google/products/ads-commerce/2021-01-privacy-sandbox/) being implemented in Google Chrome as a POC are methods based on **SimHash**, which is a type of locality-sensitive hashing initially introduced for detecting near-duplicate documents.

## Contents

<!-- toc -->

- [FLoC SimHash](#floc-simhash)
  - [Contents](#contents)
  - [Installation](#installation)
  - [Usage](#usage)
    - [Individual document-based SimHash](#individual-document-based-simhash)
      - [Providing your own tokenizer](#providing-your-own-tokenizer)
    - [Using the SimHashTransformer in scikit-learn pipelines](#using-the-simhashtransformer-in-scikit-learn-pipelines)
      - [Caveats](#caveats)
  - [Development](#development)

<!-- tocstop -->

## Installation

The `floc-simhash` package is available at PyPI. Install using `pip` as follows.

```bash
pip install floc-simhash
```

The package requires `python>=3.7` and will install `scikit-learn` as a dependency.

## Usage

The package provides two main classes.

- `SimHash`, applying the SimHash algorithm on the md5 hashes of tokens in the given document.

- `SimHashTransformer`, applying the SimHash algorithm to a document vectorization as part of a scikit-learn [pipeline](https://scikit-learn.org/stable/modules/compose.html#pipeline)

Finally, there is a third class available:

- `SortingSimHash`, which performs the SortingLSH algorithm by first applying `SimHash` and then clipping the resulting hashes to a given precision.

### Individual document-based SimHash

The `SimHash` class provides a way to calculate the SimHash of any given document, without using any information coming from other documents.

In this case, the document hash is computed by looking at md5 hashes of individual tokens.
We use:

- The implementation of the md5 hashing algorithm available in the `hashlib` module in the [Python standard library](https://docs.python.org/3/library/hashlib.html).

- Bitwise arithmetic for fast computations of the document hash from the individual hashed tokens.

The program below, for example, will print the following hexadecimal string: `cf48b038108e698418650807001800c5`.

```python
from floc_simhash import SimHash

document = "Lorem ipsum dolor sit amet consectetur adipiscing elit"
hashed_document = SimHash(n_bits=128).hash(document)

print(hashed_document)
```

An example more related to computing cohort ids:
the following program computes the cohort id of a user by applying SimHash to the document formed by the pipe-separated list of domains in the user browsing history.

```python
from floc_simhash import SimHash

document = "google.com|hybridtheory.com|youtube.com|reddit.com"
hasher = SimHash(n_bits=128, tokenizer=lambda x: x.split("|"))
hashed_document = hasher.hash(document)

print(hashed_document)
```

The code above will print the hexadecimal string: `14dd1064800880b40025764cd0014715`.

#### Providing your own tokenizer

The `SimHash` constructor will split the given document according to white space by default.
However, it is possible to pass any callable that parses a string into a list of strings in the `tokenizer` parameter.
We have provided an example above where we pass `tokenizer=lambda x: x.split("|")`.

A good example of a more complex tokenization could be passing the [word tokenizer](https://www.nltk.org/api/nltk.tokenize.html#nltk.tokenize.word_tokenize) in NLTK.
This would be a nice choice if we wished to compute hashes of text documents.

### Using the SimHashTransformer in scikit-learn pipelines

The approach to SimHash outlined in the [FLoC Whitepaper](https://raw.githubusercontent.com/google/ads-privacy/master/proposals/FLoC/FLOC-Whitepaper-Google.pdf) consists of choosing random unit vectors and working on already vectorized data.

The choice of a random unit vector is equivalent to choosing a random hyperplane in feature space.
Choosing `p` random hyperplanes partitions the feature space into `2^p` regions.
Then, a `p`-bit SimHash of a vector encodes the region to which it belongs.

It is reasonable to expect _similar_ documents to have the same hash, provided the vectorization respects the given notion of similarity.

Two vectorizations are discussed in the aforementioned whitepaper: **one-hot** and **tf-idf**; they are available in [scikit-learn](https://scikit-learn.org/stable/modules/feature_extraction.html#text-feature-extraction).

The `SimHashTransformer` supplies a transformer (implementing the `fit` and `transform` methods) that can be used directly on the output of any of these two vectorizers in order to obtain hashes.

For example, given a 1d-array `X` containing strings, each of them corresponding to a concatenation of the domains visited by a given user and separated by `"|"`, the following code will store in `y` the cohort id of each user, using one-hot encoding and a 32-bit SimHash.

```python
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline

from floc_simhash import SimHashTransformer

X = [
    "google.com|hybridtheory.com|youtube.com|reddit.com",
    "google.com|youtube.com|reddit.com",
    "github.com",
    "google.com|github.com",
]

one_hot_simhash = Pipeline(
    [
        ("vect", CountVectorizer(tokenizer=lambda x: x.split("|"), binary=True)),
        ("simhash", SimHashTransformer(n_bits=32)),
    ]
)

y = one_hot_simhash.fit_transform(X)
```

After running this code, the value of `y` would look similar to the following (expect same lengths; actual hash values depend on the choice of random vectors during `fit`):

```python
['0xd98c7e93' '0xd10b79b3' '0x1085154d' '0x59cd150d']
```

#### Caveats

- The implementation works on the sparse matrices output by `CountVectorizer` and `TfidfTransformer`, in order to manage memory efficiently.

- At the moment, the choice of precision in the numpy arrays results in overflow errors for `p >= 64`. While we are waiting for implementation details of the FLoC POCs, the first indications hint at choices around `p = 50`.

## Development

This project uses [poetry](https://python-poetry.org/) for managing dependencies.

In order to clone the repository and run the unit tests, execute the following steps on an environment with `python>=3.7`.

```bash
git clone https://github.com/hybridtheory/floc-simhash.git
cd floc-simhash
poetry install
pytest
```

The unit tests are property-based, using the [hypothesis](https://hypothesis.readthedocs.io/en/latest/) library.
This allows for algorithm veritication against hundreds or thousands of random generated inputs.

Since running many examples may lengthen the test suite runtime, we also use `pytest-xdist` in order to parallelize the tests.
For example, the following call will run up to 1000 examples for each test with parallelism 4.

```bash
pytest -n 4 --hypothesis-profile=ci
```

repository: poseidonresearch/floc-simhash

branch_name: refs/heads/main

repo_name: poseidonresearch/floc-simhash


text:
# image-inspector-client
a ruby client for [image-inspector](https://github.com/openshift/image-inspector)

## installing gem
gem install image-inspector-client

## usage
```ruby
require 'image-inspector-client'
ImageInspectorClient::Client.new('http://localhost:8080', 'v1')
  .fetch_metadata
  .ContainerConfig
  .Cmd

Get OpenSCAP ARF as raw xml:
ImageInspectorClient::Client.new('http://localhost:8080', 'v1')
  .fetch_oscap_arf

```

## building from source
fetch dependencies:
```
bundle install
```
tests:
```
rake test
```
tests and style check:
```
rake test rubocop
```

build and install into $GEM_HOME:
```
rake install
```

repository: openshift/image-inspector-client-ruby

gha_language: Ruby

repo_name: openshift/image-inspector-client-ruby


text:
---
layout: default
title: OS Dev Journey
nav_order: 3
has_children: true
permalink: /blog/os-dev-journey
---

# My Operating System Development Journey

I love to learn how things really work and build things from scratch. Since I am interested in virtualization, operating systems and work as an embedded software engineer, I wanted to give this a go. Here are some good resources:

- [OS Dev website](https://wiki.osdev.org/Expanded_Main_Page)
- [Operating Systems: Three Easy Pieces](https://pages.cs.wisc.edu/~remzi/OSTEP/)
    - There is also an online course on [educative.io](https://www.educative.io/courses/operating-systems-virtualization-concurrency-persistence) that follows this course.
- [Intel's developer manual](https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html)
- [Philipp Oppermann's blog](https://os.phil-opp.com)


text:
haskell-bitcoin-tx
==================

[![Build Status](https://travis-ci.org/solatis/haskell-bitcoin-tx.png?branch=master)](https://travis-ci.org/solatis/haskell-bitcoin-tx)
[![Coverage Status](https://coveralls.io/repos/solatis/haskell-bitcoin-tx/badge.svg?branch=master)](https://coveralls.io/r/solatis/haskell-bitcoin-tx?branch=master)
[![MIT](http://b.repl.ca/v1/license-MIT-blue.png)](http://en.wikipedia.org/wiki/MIT_License)
[![Haskell](http://b.repl.ca/v1/language-haskell-lightgrey.png)](http://haskell.org)

This library provides the same functionality as the bitcoin-tx command line
utility, which was introduced in Bitcoin Core v0.10. These functions are
pure and require no communication with a bitcoin daemon.

repository: solatis/haskell-bitcoin-tx

gha_language: Haskell

repo_name: solatis/haskell-bitcoin-tx


text:
# Fi: Financially Independent

![Static](https://img.shields.io/badge/Python-3.x-blue.svg)
![license](https://img.shields.io/github/license/mashape/apistatus.svg)

## What is Fi?
Fi is a simple python application to help you plan for your retirement by estimating your level of financial independence.

There is no need to provide Fi with all your financial information, Fi is able to compute your level of financial independence by asking you 5 simple questions:

* How much did you spend last year to support your current lifestyle.
* What is the expected inflation rate.
* How much do you currently have saved for investment.
* What is the expected average annual interest rate.
* How many years do you want to test.

Once you have answered these questions Fi will display your expected savings balance each year up to the total number of years you want to test for and let you know whether you are `Financially independent` or `Not financially independent`.

## Installing Fi

### Requirements
Fi requires **Python 3.x**.
If you need Python 3 the latest information and versions are available at
  https://www.python.org/downloads/

### Quick start
Use the Python interpreter to run Fi:

    $ python3 fi.py

## Using Fi

Fi will first ask you to enter how much money you spent last year to support your current lifestyle. The amount you enter must be a whole number that is equal to or greater than zero, for example `50000`. The amount can not be negative or contain decimals, for example `-50000` or `50000.25`. If an invalid value is entered you will be asked to re-enter the amount.

    $ How much did you spend last year to support your current lifestyle?

You will than be asked to enter the inflation rate. The inflation rate must be entered as a decimal number and not a percentage. For example 5% should be entered as `0.05`. If an invalid value is entered you will be asked to re-enter the amount.

    $ Please enter the expected inflation rate as a decimal number(e.g. 5% = 0.05):

Fi will then ask you to enter your current savings balance. The amount you enter must be a whole number and can not be negative. If an invalid value is entered you will be asked to re-enter the amount.

    $ How much do you currently have saved for investment?

You will than be asked to enter the annual interest rate that you expect to earn on your savings. The annual interest rate must be entered as a decimal number and not a percentage. If an invalid value is entered you will be asked to re-enter the amount.

    $ Please enter the expected interest rate as a decimal number(e.g. 3% = 0.03):

Finally Fi will ask you to enter the number of years that you would like to test for. The amount you enter must be a whole number that is equal to or greater than zero. The amount can not be negative or contain decimals. If an invalid value is entered you will be asked to re-enter the amount.

    $ How many years do you want to test?

### Fi example

For each year, up to the total number of years you want to test for, Fi will display the year number and the estimated savings balance for that year. If the savings balance remains positive for each year Fi will display all the years and let you know that you are `Financially independent`.

    $ How much did you spend last year to support your current lifestyle? 50000
    $ Please enter the expected inflation rate as a decimal number(e.g. 5% = 0.05): 0.02
    $ How much do you currently have saved for investment? 1000000
    $ Please enter the expected interest rate as a decimal number(e.g. 3% = 0.03): 0.05
    $ How many years do you want to test? 20
      Year    Remaining balance
         1    $996450.00
         2    $991651.50
         3    $985520.66
         4    $977969.00
         5    $968903.21
         6    $958224.84
         7    $945830.08
         8    $931609.47
         9    $915447.59
        10    $897222.76
        11    $876806.74
        12    $854064.39
        13    $828853.26
        14    $801023.29
        15    $770416.36
        16    $736865.93
        17    $700196.55
        18    $660223.45
        19    $616752.04
        20    $569577.40
      Financially independent

However if the savings balance becomes negative for any year Fi will only display up to the year where the savings balance becomes negative and let you know that you are `Not financially independent`.

    $ How much did you spend last year to support your current lifestyle? 100000
    $ Please enter the expected inflation rate as a decimal number(e.g. 5% = 0.05): 0.025
    $ How much do you currently have saved for investment? 1500000
    $ Please enter the expected interest rate as a decimal number(e.g. 3% = 0.03): 0.04
    $ How many years do you want to test? 20
      Year    Remaining balance
         1    $1453400.00
         2    $1402271.00
         3    $1346365.22
         4    $1285423.28
         5    $1219173.76
         6    $1147332.60
         7    $1069602.58
         8    $985672.78
         9    $895217.94
        10    $797897.87
        11    $693356.77
        12    $581222.61
        13    $461106.36
        14    $332601.34
        15    $195282.38
        16    $48705.09
        17    $-107595.00
      Not financially independent

## Support
If you find a bug, or have a feature suggestion, please email me at<EMAIL_ADDRESS>
## License
Fi is licensed under the terms of the [MIT](https://choosealicense.com/licenses/mit/) License.

path: /Finacial Independence Application - A1/readme.md


text:
# Creating a Kubernetes Cluster on DigitalOcean with Python and Fabric

Check out the [blog post](https://testdriven.io/creating-a-kubernetes-cluster-on-digitalocean).

## Want to use this project?

1. Fork/Clone

1. Create and activate a virtualenv

1. Install the requirements

1. [Sign up](https://m.do.co/c/d8f211a4b4c2) for Digital Ocean and [generate](https://www.digitalocean.com/docs/apis-clis/api/) an access token

1. Add the token to your environment:

    ```sh
    $ export DIGITAL_OCEAN_ACCESS_TOKEN=[your_token]
    ```

1. [Add](https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/to-account/) a public SSH key to your account.

1. Spin up the cluster:

    ```sh
    $ sh create.sh
    ```

repository: testdrivenio/kubernetes-fabric

gha_language: Shell

repo_name: testdrivenio/kubernetes-fabric


text:
---
layout: page
title: About
permalink: /about/
---

### SCOREC

The Scientific Computation Research Center (SCOREC) is focused on the
development of reliable simulation technologies for engineers, scientists,
medical professionals, and other practitioners. These advancements enable
experts in their fields to employ, appraise, and evaluate the behavior of
physical, chemical, and biological systems of interest.

Building on its historic strengths in automated adaptive modeling and
computation, SCOREC is focused on the development of the technologies necessary
to enable multiscale systems engineering. Multiscale systems engineering will
introduce a new paradigm in which all interacting scales important to the
behavior of materials, devices, and systems will be accurately modeled and
accounted for in the design optimized products and processes. To enable the
implementation of this new paradigm advanced modeling, simulation, optimization,
and control technologies must be developed to provide the basis for design
environments in which systematic exploration of alternative designs is supported
by (i) a hierarchy of models that provides a consistent description of
multiscale phenomena, (ii) adaptive simulation methods that account for the
scale interactions, (iii) efficient computational analysis, optimization and
control methods, and (iv) the representation of uncertainty and its propagation.

The interdisciplinary team of faculty, research staff and students working with
SCOREC are involved in funded research to address key research areas that must
be addressed in terms of the overall methods involved as well as their
application to specific critical application areas such as nano-composites
design and vascular disease modeling. SCOREC research programs include the
active transition of the methods and simulation technologies developed to
industrial practice and commercialization by software companies.

Visit [scorec.rpi.edu](http://scorec.rpi.edu/about_us.php) for more info.

### Contact us

Cameron W. Smith [smithc11<EMAIL_ADDRESS>
Gerrett Diamond [diamog<EMAIL_ADDRESS>
Mark S. Shephard [shephard<EMAIL_ADDRESS>

repository: SCOREC/EnGPar

repo_name: SCOREC/EnGPar


text:
# gee_monkey

<!-- > Fill this form https://forms.gle/dY9cDNJixrEbTnvb8, you will get the latest `gee_monkey`.  -->

Batch export Google Earth Engine (GEE) tasks with `Tampermonkey`.

+ Tired of click GEE tasks run button in browser?
+ Tired of translate `JavaScript` into `python`, because of `JavaScript` inconvenient batch exporting?
+ Tired of paste JavaScript into console?

__Tampermonkey can solve those problems!__

## Functions

![](image/gee_monkey_ui.png)

- **rAll** : batch run all tasks
- **rInv** : batch run all tasks in inverse order
- **cALL** : cancel all tasks
- **cSub** : only cancel `submitted-to-backend` tasks, and leave `running-on-backend` tasks
- **ntask**: How many tasks to export? If not specified, it is all tasks.

to be continue

**Tasks submitted to GEE have two kinds:**

1. `task submitted-to-backend`: just submitted and waiting in the queue
2. `task running-on-backend`: submitted and running now (in skyblue backgroud)

![](image/gee_monkey_v0.1.3.png)

## Updates

* 2021-09-22 (version 0.1.7)
  - update for `task manager`
  - `timeout` was replaced with `async`, which comes into effect for
    `confirm_all` and `runAll` in this version.

* 2020-08-14 (version 0.1.5)
  - fix user-box error

* 2019-09-17 (version 0.1.4)
  -   add `rInv` and `ntask`

* 2018-07-20
  -   `running-on-backend` task's background is set to skyblue to distinguish `submitted-to-backend` task.

## Free version
https://gis.stackexchange.com/questions/290771/batch-task-execution-in-google-earth-engine
```javascript
/**
 * Copyright (c) 2017 Dongdong Kong. All rights reserved.
 * This work is licensed under the terms of the MIT license.
 * For a copy, see <https://opensource.org/licenses/MIT>.
 *
 * Batch execute GEE Export task
 *
 * First of all, You need to generate export tasks. And run button was shown.
 *
 * Then press F12 get into console, then paste those scripts in it, and press
 * enter. All the task will be start automatically.
 * (Firefox and Chrome are supported. Other Browsers I didn't test.)
 *
 * @Author:
 *  Dongdong Kong, 28 Aug' 2017, Sun Yat-sen University
 *  yzq.yang, 17 Sep' 2021
 */
function runTaskList(){
    // var tasklist = document.getElementsByClassName('task local type-EXPORT_IMAGE awaiting-user-config');
    // for (var i = 0; i < tasklist.length; i++)
    //         tasklist[i].getElementsByClassName('run-button')[0].click();
    $$('.run-button' ,$$('ee-task-pane')[0].shadowRoot).forEach(function(e) {
         e.click();
    })
}

function confirmAll() {
    // var ok = document.getElementsByClassName('goog-buttonset-default goog-buttonset-action');
    // for (var i = 0; i < ok.length; i++)
    //     ok[i].click();
    $$('ee-table-config-dialog, ee-image-config-dialog').forEach(function(e) {
         var eeDialog = $$('ee-dialog', e.shadowRoot)[0]
         var paperDialog = $$('paper-dialog', eeDialog.shadowRoot)[0]
         $$('.ok-button', paperDialog)[0].click()
    })
}

runTaskList();
confirmAll();
```
## Pro version

![](image/gee_monkey_v0.1.7.gif)

## Installation

You need `chrome` and [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) (`firefox` is also OK).
You also can submit tasks by your phone with `firefox` and `Tampermonkey`.

+ 1 Install [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) extension in `chrome` or `firefox`.
+ 2 Dashboard → New script → paste the script in [gee_monkey](https://github.com/kongdd/GEE_Tools/blob/master/gee_monkey.js) → F5 refresh GEE website.

![](image/s2_gee_monkey.gif)


text:
---
title: "Directory Browsing"
alertid: 0
alertindex: 0
alerttype: "Active"
alertcount: 1
status: release
type: alert
risk: Medium
solution: "Disable directory browsing.  If this is required, make sure the listed files does not induce risks."
references:
   - http://httpd.apache.org/docs/mod/core.html#options
   - http://alamo.satlug.org/pipermail/satlug/2002-February/000053.html
other: ""
cwe: 548
wasc: 48
alerttags:
  - OWASP_2017_A05
  - OWASP_2021_A01
code: https://github.com/zaproxy/zap-extensions/blob/main/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/DirectoryBrowsingScanRule.java
linktext: "org/zaproxy/zap/extension/ascanrules/DirectoryBrowsingScanRule.java"
---
It is possible to view the directory listing.  Directory listing may reveal hidden scripts, include files, backup source files, etc. which can be accessed to read sensitive information.

repository: zaproxy/zaproxy-website

gha_language: HTML

repo_name: zaproxy/zaproxy-website


text:
This endpoint represents a mapping between [Users](/api/users/) and
[Goals](/api/goals/).

GET requests to this page will simply list this mapping for the authenticated
user.

## Fields

This endpoint returns resources with the following fields.

* `id`: A unique identifier for the `UserGoal` mapping.
* `user`: A unique identifier for the `User`
* `goal`: An object that represents the `Goal` selected by the user
* `user_categories`: An array of `Category` objects selected by the user,
  that are also parents of this goal.
* `primary_category`: The primary category for this goal, based on the
  user's selection.
* `created_on`: Time at which the user selected this item.
* `progress_value`: The user's self-reported progress toward this goal.
* `goal_progress`: An object containing information on the user's progress
  toward the completion of their scheduled actions within this goal. It
  contains the following information:

    - `id`: a unique id for the GoalProgress instance.
    - `goal`: the goal's unique id
    - `usergoal`: The unique id of the parent UserGoal
    - `current_score`: The aggregate reporting score.
    - `current_total`: The sum of user-reported progresses within this goal.
    - `max_total`: The maximum possible value for the reported score.
    - `daily_actions_total`: Number of actions scheduled for _this day_.
    - `daily_actions_completed`: Number of actions the user completed in
      _this day_
    - `daily_action_progress`: Daily progress percentage (as a float). This
      is calculated with `daily_actions_completed` / `daily_actions_total`
    - `daily_action_progress_percent`: The daily progress expressed as an
      integer percentage.
    - `weekly_actions_total`: Number of actions scheduled for the past 7 days
    - `weekly_actions_completed`: Number of actions completed over the past
      7 days
    - `weekly_action_progress`: Percentage of completed actions for the week.
    - `weekly_action_progress_percent`: The weekly progress expressed as an
      integer percentage.
    - `actions_total`:  Number of actions scheduled for our historical
      reporting period
    - `actions_completed`: Number of actions completed during our historical
      reporting period.
    - `action_progress`:  Percentage of actions completed (as a float) during
      the historical reporting period.
    - `action_progress_percent`: The progress expressed as an integer
      percentage.
    - `reported_on`: Date/Time on which this data was recorded.

* `custom_triggers_allowed`: A boolean that indicates whether or not a user
  should be able to customize the reminders beneath this content

## Adding a Goal

To associate a Goal with a User, POST to `/api/users/goals/` with the
following data:

    {'goal': GOAL_ID}

## Adding multiple Goals in one request

This endpoint also allows you to associate multiple goals with a user
in a single request. To do this, POST an array of goal IDs, e.g.:

    [
        {'goal': 3},
        {'goal': 4},
        {'goal': 5}
    ]

## Removing multiple Goals in one request.

This endpoint also allows you to remove  multiple instances of the
user-to-goal association. Tod do this, send a DELETE request with
an array of `usergoal` IDs, e.g.:

    [
        {'usergoal': 3},
        {'usergoal': 4},
        {'usergoal': 5}
    ]

## Viewing the Goal data

Additional information for the Goal mapping is available at
`/api/users/goals/{usergoal_id}/`. In this case, `{usergoal_id}` is the
database id for the mapping between a user and a goal.

## Removing a Goal from the user's list.

Send a DELETE request to the usergoal mapping endpoint:
`/api/users/goals/{usergoal_id}/`.

## Update a Goal Mapping.

Updating a goal mapping is currently not supported.

## Additional information

The Goals that a User has selected are also available through the
`/api/users/` endpoint as a `goals` object on the user.

Each results object also includes a `user_categories` object in addition to
a `goal` object. The `user_categories` object is a list of Categories in
which the goal belongs that have also been selected by the User. Related:
[/api/users/categories/](/api/users/categories/).

----

gha_language: Python


text:
# Contributing

Thank you for taking the time to contribute to job-history! There are just a few things to be aware of when contributing to this project.

## Code of Conduct
First, please follow the [Code of Conduct](CODE_OF_CONDUCT.md).

## Filing Issues
Second, when filing issues or bugs, please try to fill out the complete template as much as possible. This will help save time in the long run.

## Pull Requests
When submitting a Pull Request, try to fill that template out thoroughly, as well. Link any related issues, with [closing keywords](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), if appropriate.

## Code Conventions
In general, please follow general Python/Django style guidelines, as well as the conventions you see used in the project already.

Thanks once again!

repository: stephengtuggy/job-history

repo_name: stephengtuggy/job-history


text:
***
  ## READMe Generator
  ***

  Employee Summary

  Employee Summar is a CLI application that will prompt the user for employee info. Based on user input, after all the prompt questions are answered an HTML file called team.html is generated. This file can be viewed on the browser, and it will display team and employee info

  ![License: MIT](https://img.shields.io/badge/License-Apache%202.0-blue.svg)

  ***
  ## Table of Contents:
  1. [How to Install Employee Summary](#Installation)
  2. [Using Employee Summary](#How%20To%20Use%20This%20Application)
  3. [Testing Employee Summary](#Test%20Code)
  4. [View Employee Summary Demo ](#Demo)
  5. [Link to the Deployed Employee Summary App in Github ](#Link%20to%20the%20Deployed%20App%20in%20Github)
  6. [Ask Us Questions](#Ask%20Questions)
  7. [Licenses](#License)
  ***

  ## Installation
  Clone the repository https://github.com/purilisa/EmployeeSummary from github to your machine. Run the app using "node app" command. This will start the application.

  ## How to Use This Application
  Once application is installed, run the app and respond to the prompts that will ask for role, name, id, number, email. Depending on the role, you will get different prompts. Once you have completed entering employees, select no when prompted for "add another employee" the application will generate a team.html file that contains team information.

  ## Test Code
  The test folder has all tests related to the application. To run the tests, enter "npm run test" in your command line.

  ## Demo
  Click here: https://drive.google.com/file/d/1CS2cM227oCga6woJmQ9KsYMQTClzNKk7/view

  ## Link to the Deployed App in Github
  https://github.com/purilisa/EmployeeSummary

  ## Ask Questions
  Visit my GitHub Page: [My GitHub Profile Page](https://github.com/purilisa)
 -OR-
 Drop me an e-mail at<EMAIL_ADDRESS>

  ## License
  This applicaton is covered under the Apache License 2.0

repository: purilisa/EmployeeSummary

repo_name: purilisa/EmployeeSummary


text:
# CurrencyFWK
macOS/iOS framework for easy currency conversion (yahoo api)

To get started, first of all, import `CurrencyFWK.framework` to your app.

```swift
// Swift
import CurrencyFWK
```

Then, before using it, implement an instance of converter

```swift
// Swift
let converter = CurrencyRetrievalKit.sharedInstance
```

The function, you're looking for is `convert(from sourceCurrency: String, to destinationCurrency: String, forced: Bool = false, completion: ((Double)->())? = nil)`

Function takes string values, like "USD", "EUR", "GBP" etc.; boolean value for force retrieval or not (I recommend "false") and in completion handler it returns conversion rate, meaning, for example, 1USD/1EUR.

Some func are written, using [Alamofire](https://github.com/Alamofire/Alamofire/), it's located in the "Frameworks" folder of CurrencyFWK.framework

It's my first framework, don't be too strict.

repository: answerfan/CurrencyFWK

repo_name: answerfan/CurrencyFWK


text:
[![Go Report Card](https://goreportcard.com/badge/github.com/hasansino/kafka-replicator)](https://goreportcard.com/report/github.com/hasansino/kafka-replicator)
[![Build Status](https://travis-ci.com/hasansino/kafka-replicator.svg?branch=master)](https://travis-ci.com/hasansino/kafka-replicator)

# Kafka replicator

Replicates data from local kafka to main kafka cluster.
It uses sarama under the hood with group consumer and sync producer.

## Build

`make build` to build binary file for linux.
`make image` to build image `hasansino/kafka-replicator:latest`

## Usage

```bash
usage: tsctl [<flags>]

Flags:
  --help                      Show context-sensitive help (also try --help-long and --help-man).
  --group="mirrormaker"       The name of the consumer group
  --topics=""                 The comma-separated list of topics to consume
  --rewrite=""                The rewrite rules (--rewrite="from-topic-name->to-topic-name,from-topic-name2->to-topic-name2")
  --consume-brokers=""        A comma-separated broker connection string (localhost:9092, localhost:9092)
  --produce-brokers=""        A comma-separated broker connection string (localhost:9092, localhost:9092)
  --compression="none"        The compression codec to be used by the producer (none, gzip, snappy, lz4)
  --offset-initial="oldest"   The initial offset method (oldest, newest)
  --batch-size=10000          The maximum count of messages in batch request
  --flush-interval=1s         The flush interval in millisecond
  --session-timeout=1m        Kafka session timeout
  --partitioner="roundrobin"  partitioner to use (random, keyhash, roundrobin)
```

repository: hasansino/kafka-replicator

repo_name: hasansino/kafka-replicator


text:
---
layout: post
title: 'Community: Drupal Sevilla is moving'
permalink: /blog/community-drupal-sevilla-is-moving
published: true
date: 2017-06-30
author: davidjguru
categories: [Community & Events]
sitemap: true
---
| ![Picture from Unsplash, by @tegan]({{ site.baseurl }}/images/davidjguru_drupal_8_drupal_sevilla_moving_group.png) |
|:--:|
| *Picture from Unsplash, user Tegan Mierle @tegan* |

This week the local group [Drupal Sevilla](https://groups.drupal.org/sevilla){:target="_blank"} -the community of people interested in Drupal living and working from Seville (Andalusia, Spain)- has met and we have done a retrospective on the cycle of activities developed to date, taking advantage of the last appointment before Of summer to review and prepare ideas for the new course that will begin in September.
 <!--more-->

The life of the local group Drupal Sevilla began six years ago (2011) related to the first organization of a medium-sized event in Seville, DrupalCamp Spain 2011 and from there has had a complex life cycle, with periodic stops and reactivations , But it is true that in recent times has had a constant activity, diverse and even with the production of important events such as Drupal Developer Days 2017 here in Seville. And it's been a very busy year :-)

For these reasons, we meet in [Bodega Aurora](https://www.facebook.com/bodegaaurorasevilla/){:target="_blank"} (one of the oldest bars in Seville) [José Luis Bellido](https://twitter.com/jose_lakatos){:target="_blank"}, [Diego Marrufo](https://twitter.com/Dimaro_){:target="_blank"}, [Joe Carvajal](https://twitter.com/raistlinjoe){:target="_blank"}, [Carmen García](https://twitter.com/mcgarcia_wq){:target="_blank"}, [Isaura Galafate](https://twitter.com/Isaurich){:target="_blank"}, [Christian López](https://twitter.com/penyaskito){:target="_blank"} and /me [David Rodríguez](https://twitter.com/davidjguru){:target="_blank"}.

![Drupal Sevilla June Poster]({{ site.baseurl }}/images/drupal_svq_junio_2017.png)

## What have we done during this cycle of activities?

We have treated different topics from different dimensions: site-building, development, content, SEO ... here is a list of activities carried out (written in Spanish)

* March 2017: [Drupal Developer Days Seville 2017](https://seville2017.drupaldays.org/){:target="_blank"}

* February 2017: [XML_Sitemap Module](https://groups.drupal.org/node/516139){:target="_blank"}

* January 2017: [Drupal Global Sprint Weekend Seville](https://groups.drupal.org/node/515870){:target="_blank"}

* November  2017: [Write testaable code on Drupal 8](https://groups.drupal.org/node/515218){:target="_blank"}

* October 2017: [SEO on Drupal: modules and contents](https://groups.drupal.org/node/514669){:target="_blank"}

* September 2017: [An introduction to Rules, a Drupal module](https://groups.drupal.org/node/513637){:target="_blank"}

![Visual resume Drupal Sevilla]({{ site.baseurl }}/images/drupal_sevilla_review.png )

## And what about our community?

The term "community", is a relatively abstract element, becomes an empty term at the cost of different uses in different contexts. When we’re talking ‘bout community, we may be dealing with different senses, which makes the term a relatively floating expression. To avoid this and based on the basic definition, understood as a group of people with a common interest who self-organize (in its most horizontal sense, indeed), the first fundamental question is to try to grant an "anchor" to the term that Allow us to place the term in the frame that we really consider our interest. And the fundamental tool could be the so-called "needs analysis". If the sense of belonging to a community is determined (among other factors) by the need for improvement when combined with other people, then the best we can do is to try to define specifically what we need, which we hope will give us our own militancy

* Improve our developer skills

* Test code and modules before launch

* Frontend Workshops and Training

* Outreach activities and success stories

* Contribution Sessions and Patching

## What would we like to continue doing?

1- We would like to keep meeting once a month

2- Combined activities of different level and approach

3- Bring Drupal to schools

**A very important step is to try to agree on a gender and diversity policy** according to the current times, echoing all the problems of the integration of women and people of non-binary gender within society in general and the technological sector in particular. The local group Drupal Sevilla is committed to seek parity in its activities and its sessions.
We are looking forward to doing more things throughout the new course that will start in September, with the memory of a year of activities and of course, the pride of having brought to our city a great reference event as the [Drupal Developer Days 2017](https://www.flickr.com/groups/drupaldevdays2017/){:target="_blank"} .

![Drupal Developer Days Seville 2017 family picture]({{ site.baseurl }}/images/drupal_developer_days.png )

Do you want a more extensive review? [Here's a better one](https://groups.drupal.org/node/517058){:target="_blank"}
(but you'll have to read it in Spanish). Greetings to all.

:wq!


text:
# Project Setup

## Software Requirements

The following software is required to build the project:

### Windows

* [Arduino](https://www.arduino.cc/en/Main/Software) installation with [Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) add-on
* Git for Windows \(Bash\)
* MinGW \(make\)
* Visual Studio 2017 \(for Management UI builds\)
* Qt 5 \(for Management UI builds\)

{% hint style="info" %}
This project uses Makefile, however build tools and board files are copied from an [Arduino](https://www.arduino.cc/en/Main/Software)/[Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) installation.
{% endhint %}

{% hint style="warning" %}
If needed, copy `MinGW/bin/mingw32-make.exe` to `MinGW/bin/make.exe`, as this documentation refers to the command as `make`.
{% endhint %}

Requirements to regenerate protobuf \([nanopb](https://github.com/nanopb/nanopb)\) sources:

1. Download protoc binaries, fe.: [https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-win64.zip](https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-win64.zip)
2. Extract zip, fe. c:\share\protoc-3.11.4
3. Add protoc \(fe., c:\share\protoc-3.11.4\bin\) to PATH

### Ubuntu 18.04

* [Arduino](https://www.arduino.cc/en/Main/Software) installation with [Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) add-on
* `apt install build-essential`
* Qt 5 \(for Management UI builds\)

{% hint style="info" %}
This project uses Makefile, however build tools and board files are copied from an [Arduino](https://www.arduino.cc/en/Main/Software)/[Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) installation.
{% endhint %}

Requirements to regenerate protobuf \([nanopb](https://github.com/nanopb/nanopb)\) sources:

* `apt install protobuf libprotobuf-dev python-protobuf`

{% hint style="info" %}
To communicate with the Teensy hardware as a **non-root user**, install the [Teensy udev rule](https://www.pjrc.com/teensy/49-teensy.rules):

```text
sudo cp teensy_fan_controller/tools/49-teensy.rules /etc/udev/rules.d/
```
{% endhint %}

## Fetching sources

Use `git` to clone the root project \([TeensyFanController](https://github.com/mstrthealias/TeensyFanController)\).

You must initialize and pull the git sub-modules/sub-repositories:

```text
git clone https://github.com/mstrthealias/TeensyFanController.git
git submodule init
git submodule update
```

{% hint style="info" %}
Use the `ui_qt5` sub-directory underneath the root project directory for Management UI builds.
{% endhint %}

## Setup project build environment

Change directory to the project root, and use Makefile:

```text
cd TeensyFanController
ARDUINO_DIR=/opt/Arduino make
```

{% hint style="info" %}
Root Make targets:

* `make` alias for `make setup`
* `make setup` alias for `make clean setup-toolchain setup-libs setup-nanopb protos`
* `make setup-toolchain` copy toolchain and Teensy3 cores from [Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) into project
* `make setup-libs` copy [Teensyduino](https://www.pjrc.com/teensy/teensyduino.html) libraries into project
* `make setup-nanopb` copy [nanopb](https://github.com/nanopb/nanopb) into project libraries
* `make protos` alias for `make runtime_config_v1.pb.c`
* `make runtime_config_v1.pb.c` generate RuntimeConfigV1 protobuf sources
* `make clean` alias for `make clean-build clean-setup`
* `make clean-build` delete builds produced by `teensy_fan_controller/Makefile`
* `make clean-setup` delete files produced by this Makefile
{% endhint %}

repository: lattic/TeensyFanController

repo_name: lattic/TeensyFanController


text:
ReSharper PowerToys Pack — Source Code
----

[![obsolete JetBrains project](http://jb.gg/badges/obsolete-flat-square.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)

Note: this file is provided for a quick reference only.

The JetBrains ReSharper PowerToys Pack comprises a set of sample projects that illustrate basic techniques for ReSharper plugin development.
The samples are intended as a quickstart basis for building third-party ReSharper plugins, especially the plugin installers.
Their source code may be freely used under the BSD License.

1. Folders.

    * Bin — the output folder for the binaries built out of the source code, and for the installers. The latter also use it as input folder for the plugin binaries to be included with the installation package.
    * Build — the main build file.
    * Doc — documentation on the PowerToys and ReSharper.
    * Obj — intermediate directory for the build process temporary files (relocated from under the projects).
    * Setup — the common infrastructure for the PowerToy installers.
    * Src — the source code for the PowerToy sample plugins.
    * Lib - libraries required to build PowerToys

1. Before you compile.

    To set up the freshly downloaded set of sources for local compilation, you should copy to Lib/ReSharper files from Bin folder of local R# installation. From this point on, you may open the solution in Visual Studio.

    Then, download and install a WiX version that is compatible with the samples, and correct the WiX location paths (see .Targets file that is included into each Setup project).

2. Building.

    The Build/Build.proj file is the central build facility for both the source code and the installers. See the file itself for more detailed instructions. This file is an MSBuild build script.

3. Writing own R# Plugins.

    There are no special requirements for the plugin projects or DLLs.

    Building an installer for a plugin takes no more than setting up a few properties in the build file, provided that it's based on the infrastructure given by the PowerToys Pack; see setup build files for a self-descriptive example.

repository: JetBrains/ReSharperPowerToys

repo_name: JetBrains/ReSharperPowerToys