{"id":13414105,"url":"https://github.com/cep21/circuit","last_synced_at":"2025-05-15T20:07:21.868Z","repository":{"id":37493004,"uuid":"115224966","full_name":"cep21/circuit","owner":"cep21","description":"An efficient and feature complete Hystrix like Go implementation of the circuit breaker pattern.","archived":false,"fork":false,"pushed_at":"2025-05-06T22:03:26.000Z","size":1043,"stargazers_count":779,"open_issues_count":3,"forks_count":48,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-06T23:18:40.131Z","etag":null,"topics":["circuit","circuit-breaker-pattern","hystrix","slo"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cep21.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-23T22:17:43.000Z","updated_at":"2025-05-06T22:03:29.000Z","dependencies_parsed_at":"2024-06-18T13:53:07.311Z","dependency_job_id":null,"html_url":"https://github.com/cep21/circuit","commit_stats":{"total_commits":124,"total_committers":10,"mean_commits":12.4,"dds":"0.13709677419354838","last_synced_commit":"41a5428120d430c19eeff1888d85f6d93304e4cc"},"previous_names":["cep21/hystrix"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cep21%2Fcircuit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cep21%2Fcircuit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cep21%2Fcircuit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cep21%2Fcircuit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cep21","download_url":"https://codeload.github.com/cep21/circuit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414499,"owners_count":22067272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circuit","circuit-breaker-pattern","hystrix","slo"],"created_at":"2024-07-30T20:01:57.826Z","updated_at":"2025-05-15T20:07:16.807Z","avatar_url":"https://github.com/cep21.png","language":"Go","readme":"\u003c!-- Image designed by Jack Lindamood, Licensed under the Creative Commons 3.0 Attributions license, originate from\nhttps://github.com/golang-samples/gopher-vector design by Takuya Ueda --\u003e\n![Mascot](https://cep21.github.io/circuit/imgs/hystrix-gopher_100px.png)\n# Circuit\n[![Build Status](https://github.com/cep21/circuit/workflows/Test/badge.svg?branch=master\u0026event=push)](https://github.com/cep21/circuit/actions)\n[![GoDoc](https://godoc.org/github.com/cep21/circuit?status.svg)](https://pkg.go.dev/github.com/cep21/circuit/v4)\n[![Coverage Status](https://coveralls.io/repos/github/cep21/circuit/badge.svg)](https://coveralls.io/github/cep21/circuit)\n\nCircuit is an efficient and feature complete [Hystrix](https://github.com/Netflix/Hystrix) like Go implementation of\nthe [circuit breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker).\nLearn more about the problems Hystrix and other circuit breakers solve on the\n[Hystrix Wiki](https://github.com/Netflix/Hystrix/wiki).  A short summary of advantages are:\n\n* A downstream service failed and all requests hang forever.  Without a circuit, your service would also hang forever.\n  Because you have a circuit, you detect this failure quickly and can return errors quickly while waiting for the\n  downstream service to recover.\n* Circuits make great monitoring and metrics boundaries, creating common metric names for the common downstream failure\n  types.  This package goes further to formalize this in a SLO tracking pattern.\n* Circuits create a common place for downstream failure fallback logic.\n* Downstream services sometimes fail entirely when overloaded.  While in a degraded state, circuits allow you to push\n  downstream services to the edge between absolute failure and mostly working.\n* Open/Close state of a circuit is a clear early warning sign of downstream failures.\n* Circuits allow you to protect your dependencies from abnormal rushes of traffic.\n\nThere are a large number of examples on the [godoc](https://godoc.org/github.com/cep21/circuit#pkg-examples) that are\nworth looking at.  They tend to be more up to date than the README doc.\n\n# Feature set\n\n* No forced goroutines\n* recoverable panic()\n* Integrated with context.Context\n* Comprehensive metric tracking\n* Efficient implementation with Benchmarks\n* Low/zero memory allocation costs\n* Support for [Netflix Hystrix dashboards](https://github.com/Netflix/Hystrix/wiki/Dashboard), even with custom\n  circuit transition logic\n* Multiple error handling features\n* Expose circuit health and configuration on expvar\n* SLO tracking\n* Customizable state transition logic, allowing complex circuit state changes\n* Live configuration changes\n* Many tests and examples\n* Good inline documentation\n* Generatable interface wrapping support with https://github.com/twitchtv/circuitgen\n* Support for [Additive increase/multiplicative decrease](https://github.com/cep21/aimdcloser)\n* Prometheus [metrics collector](https://github.com/jiacai2050/prometrics).\n\n# Upgrading\n\nSee [UPGRADE_GUIDE.md](./UPGRADE_GUIDE.md) for upgrade instructions if you're upgrading from v3 to v4.\n\n# Usage\n\n## [Hello world circuit](https://godoc.org/github.com/cep21/circuit#example-Manager-MustCreateCircuit-Helloworld)\n\nThis example shows how to create a hello-world circuit from the circuit manager\n\n```go\n// Manages all our circuits\nh := circuit.Manager{}\n// Create a circuit with a unique name\nc := h.MustCreateCircuit(\"hello-world\")\n// Call the circuit\nerrResult := c.Execute(context.Background(), func(ctx context.Context) error {\n  return nil\n}, nil)\nfmt.Println(\"Result of execution:\", errResult)\n// Output: Result of execution: \u003cnil\u003e\n```\n\n## [Hello world fallback](https://godoc.org/github.com/cep21/circuit#example-Circuit-Execute-Fallbackhelloworld)\n\nThis example shows how fallbacks execute to return alternate errors or provide\nlogic when the circuit is open.\n\n```go\n// You can create circuits without using the manager\nc := circuit.NewCircuitFromConfig(\"hello-world-fallback\", circuit.Config{})\nerrResult := c.Execute(context.Background(), func(ctx context.Context) error {\n\treturn errors.New(\"this will fail\")\n}, func(ctx context.Context, err error) error {\n\tfmt.Println(\"Circuit failed with error, but fallback returns nil\")\n\treturn nil\n})\nfmt.Println(\"Execution result:\", errResult)\n// Output: Circuit failed with error, but fallback returns nil\n// Execution result: \u003cnil\u003e\n```\n\n## [Running inside a Goroutine](https://godoc.org/github.com/cep21/circuit#example-Circuit-Go)\n\nIt is recommended to use `circuit.Execute` and a context aware function.  If, however, you want to exit\nyour run function early and leave it hanging (possibly forever), then you can call `circuit.Go`.\n\n```go\nh := circuit.Manager{}\nc := h.MustCreateCircuit(\"untrusting-circuit\", circuit.Config{\n  Execution: circuit.ExecutionConfig{\n    // Time out the context after a few ms\n    Timeout: time.Millisecond * 30,\n  },\n})\n\nerrResult := c.Go(context.Background(), func(ctx context.Context) error {\n  // Sleep 30 seconds, way longer than our timeout\n  time.Sleep(time.Second * 30)\n  return nil\n}, nil)\nfmt.Printf(\"err=%v\", errResult)\n// Output: err=context deadline exceeded\n```\n\n## Hystrix Configuration\n\nAll configuration parameters are documented in config.go.  Your circuit open/close logic configuration is documented\nwith the logic.  For hystrix, this configuration is in closers/hystrix and well documented on\n[the Hystrix wiki](https://github.com/Netflix/Hystrix/wiki/Configuration).\n\nThis example configures the circuit to use Hystrix open/close logic with the default Hystrix parameters\n\n```go\nconfiguration := hystrix.Factory{\n  // Hystrix open logic is to open the circuit after an % of errors\n  ConfigureOpener: hystrix.ConfigureOpener{\n    // We change the default to wait for 10 requests, not 20, before checking to close\n    RequestVolumeThreshold: 10,\n    // The default values match what hystrix does by default\n  },\n  // Hystrix close logic is to sleep then check\n  ConfigureCloser: hystrix.ConfigureCloser{\n    // The default values match what hystrix does by default\n  },\n}\nh := circuit.Manager{\n  // Tell the manager to use this configuration factory whenever it makes a new circuit\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{configuration.Configure},\n}\n// This circuit will inherit the configuration from the example\nc := h.MustCreateCircuit(\"hystrix-circuit\")\nfmt.Println(\"This is a hystrix configured circuit\", c.Name())\n// Output: This is a hystrix configured circuit hystrix-circuit\n```\n\n## [Enable dashboard metrics](https://godoc.org/github.com/cep21/circuit/metriceventstream#example-MetricEventStream)\n\nDashboard metrics can be enabled with the MetricEventStream object. This example creates an event stream handler,\nstarts it, then later closes the handler\n\n```go\n// metriceventstream uses rolling stats to report circuit information\nsf := rolling.StatFactory{}\nh := circuit.Manager{\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{sf.CreateConfig},\n}\nes := metriceventstream.MetricEventStream{\n  Manager: \u0026h,\n}\ngo func() {\n  if err := es.Start(); err != nil {\n    log.Fatal(err)\n  }\n}()\n// ES is a http.Handler, so you can pass it directly to your mux\nhttp.Handle(\"/hystrix.stream\", \u0026es)\n// ...\nif err := es.Close(); err != nil {\n  log.Fatal(err)\n}\n// Output:\n```\n\n## [Enable expvar](https://godoc.org/github.com/cep21/circuit#example-Manager-Var)\n\nIf you wanted to publish hystrix information on Expvar, you can register your manager.\n\n```go\nh := circuit.Manager{}\nexpvar.Publish(\"hystrix\", h.Var())\n```\n\n## [Custom metrics](https://godoc.org/github.com/cep21/circuit#example-Config--Custommetrics)\n\nImplement interfaces CmdMetricCollector or FallbackMetricCollector to know what happens with commands or fallbacks.\nThen pass those implementations to configure.\n\n```go\nconfig := circuit.Config{\n  Metrics: circuit.MetricsCollectors{\n    Run: []circuit.RunMetrics{\n      // Here is where I would insert my custom metric collector\n    },\n  },\n}\ncircuit.NewCircuitFromConfig(\"custom-metrics\", config)\n```\n\n## [Panics](https://godoc.org/github.com/cep21/circuit#example-Circuit-Execute-Panics)\n\nCode executed with `Execute` does not spawn a goroutine and panics naturally go up the call stack to the caller.\nThis is also true for `Go`, where we attempt to recover and throw panics on the same stack that\ncalls Go.  This example will panic, and the panic can be caught up the stack.\n\n ```go\nh := circuit.Manager{}\nc := h.MustCreateCircuit(\"panic_up\")\n\ndefer func() {\n  r := recover()\n  if r != nil {\n    fmt.Println(\"I recovered from a panic\", r)\n  }\n}()\nc.Execute(context.Background(), func(ctx context.Context) error {\n  panic(\"oh no\")\n}, nil)\n// Output: I recovered from a panic oh no\n```\n\n## [Runtime configuration changes](https://godoc.org/github.com/cep21/circuit/closers/hystrix#example-Closer-SetConfigThreadSafe)\n\nMost configuration properties on\n[the Hystrix Configuration page](https://github.com/Netflix/Hystrix/wiki/Configuration) that say they are modifyable at\nruntime can be changed on the Circuit in a thread safe way.  Most of the ones that cannot are related to stat\ncollection.\n\nThis example shows how to update hystrix configuration at runtime.\n\n```go\n// Start off using the defaults\nconfiguration := hystrix.ConfigFactory{}\nh := circuit.Manager{\n  // Tell the manager to use this configuration factory whenever it makes a new circuit\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{configuration.Configure},\n}\nc := h.MustCreateCircuit(\"hystrix-circuit\")\nfmt.Println(\"The default sleep window\", c.OpenToClose.(*hystrix.Closer).Config().SleepWindow)\n// This configuration update function is thread safe.  We can modify this at runtime while the circuit is active\nc.OpenToClose.(*hystrix.Closer).SetConfigThreadSafe(hystrix.ConfigureCloser{\n  SleepWindow: time.Second * 3,\n})\nfmt.Println(\"The new sleep window\", c.OpenToClose.(*hystrix.Closer).Config().SleepWindow)\n// Output:\n// The default sleep window 5s\n// The new sleep window 3s\n```\n\n## [Not counting early terminations as failures](https://godoc.org/github.com/cep21/circuit#example-Circuit--Noearlyterminate)\n\nIf the context passed into a circuit function ends, before the circuit can\nfinish, it does not count the circuit as unhealthy.  You can disable this\nbehavior with the `IgnoreInterrupts` flag.\n\nThis example proves that terminating a circuit call early because the passed in context died does not, by default,\ncount as an error on the circuit.  It also demonstrates setting up internal stat collection by default for all\ncircuits\n\n```go\n// Inject stat collection to prove these failures don't count\nf := rolling.StatFactory{}\nmanager := circuit.Manager{\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{\n    f.CreateConfig,\n  },\n}\nc := manager.MustCreateCircuit(\"don't fail me bro\")\n// The passed in context times out in one millisecond\nctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)\ndefer cancel()\nerrResult := c.Execute(ctx, func(ctx context.Context) error {\n  select {\n  case \u003c- ctx.Done():\n    // This will return early, with an error, since the parent context was canceled after 1 ms\n    return ctx.Err()\n  case \u003c- time.After(time.Hour):\n    panic(\"We never actually get this far\")\n  }\n}, nil)\nrs := f.RunStats(\"don't fail me bro\")\nfmt.Println(\"errResult is\", errResult)\nfmt.Println(\"The error and timeout count is\", rs.ErrTimeouts.TotalSum() + rs.ErrFailures.TotalSum())\n// Output: errResult is context deadline exceeded\n// The error and timeout count is 0\n```\n\n## [Configuration factories](https://godoc.org/github.com/cep21/circuit#example-CommandPropertiesConstructor)\n\nConfiguration factories are supported on the root manager object.  This allows you to create dynamic configuration per\ncircuit name.\n\nYou can use DefaultCircuitProperties to set configuration dynamically for any circuit\n\n```go\nmyFactory := func(circuitName string) circuit.Config {\n  timeoutsByName := map[string]time.Duration{\n    \"v1\": time.Second,\n    \"v2\": time.Second * 2,\n  }\n  customTimeout := timeoutsByName[circuitName]\n  if customTimeout == 0 {\n    // Just return empty if you don't want to set any config\n    return circuit.Config{}\n  }\n  return circuit.Config{\n    Execution: circuit.ExecutionConfig{\n      Timeout: customTimeout,\n    },\n  }\n}\n\n// Hystrix manages circuits with unique names\nh := circuit.Manager{\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{myFactory},\n}\nh.MustCreateCircuit(\"v1\")\nfmt.Println(\"The timeout of v1 is\", h.GetCircuit(\"v1\").Config().Execution.Timeout)\n// Output: The timeout of v1 is 1s\n```\n\n## [Service health tracking](https://godoc.org/github.com/cep21/circuit/metrics/responsetimeslo#example-Factory)\n\nMost services have the concept of an SLA, or service level agreement.  Unfortunantly,\nthis is usually tracked by the service owners, which creates incentives for people to\ninflate the health of their service.\n\nThis Circuit implementation formalizes an SLO of the template\n\"X% of requests will return faster than Y ms\".  This is a value that canont be calculated\njust by looking at the p90 or p99 of requests in aggregate, but must be tracked per\nrequest.  You can define a SLO for your service, which is a time **less** than the timeout\ntime of a request, that works as a promise of health for the service.  You can then\nreport per circuit not just fail/pass but an extra \"healthy\" % over time that counts only\nrequests that resopnd _quickly enough_.\n\nThis example creates a SLO tracker that counts failures at less than 20 ms.  You\nwill need to provide your own Collectors.\n\n```go\nsloTrackerFactory := responsetimeslo.Factory{\n  Config: responsetimeslo.Config{\n    // Consider requests faster than 20 ms as passing\n    MaximumHealthyTime: time.Millisecond * 20,\n  },\n  // Pass in your collector here: for example, statsd\n  CollectorConstructors: nil,\n}\nh := circuit.Manager{\n  DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{sloTrackerFactory.CommandProperties},\n}\nh.CreateCircuit(\"circuit-with-slo\")\n```\n\n## [Not counting user error as a fault](https://godoc.org/github.com/cep21/circuit#example-BadRequest)\n\nSometimes users pass invalid functions to the input of your circuit.  You want to return\nan error in that case, but not count the error as a failure of the circuit.  Use `SimpleBadRequest`\nin this case.\n\nThis example shows how to return errors in a circuit without considering the circuit at fault.\nHere, even if someone tries to divide by zero, the circuit will not consider it a failure even if the\nfunction returns non nil error.\n\n```go\nc := circuit.NewCircuitFromConfig(\"divider\", circuit.Config{})\ndivideInCircuit := func(numerator, denominator int) (int, error) {\n  var result int\n  err := c.Run(context.Background(), func(ctx context.Context) error {\n    if denominator == 0 {\n      // This error type is not counted as a failure of the circuit\n      return \u0026circuit.SimpleBadRequest{\n        Err: errors.New(\"someone tried to divide by zero\"),\n      }\n    }\n    result = numerator / denominator\n    return nil\n  })\n  return result, err\n}\n_, err := divideInCircuit(10, 0)\nfmt.Println(\"Result of 10/0 is\", err)\n// Output: Result of 10/0 is someone tried to divide by zero\n```\n\n# Benchmarking\n\nThis implementation is more efficient than go-hystrix in every configuration.  It has comparable efficiency\nto other implementations, faster for most when running with high concurrency.\n\nThe benchmarking code is available [here](https://github.com/cep21/circuit-benchmarks). Run benchmarks with `make bench`.\n\nI benchmark the following alternative circuit implementations.  I try to be fair and if\nthere is a better way to benchmark one of these circuits, please let me know!\n\n* [hystrix-go](https://github.com/afex/hystrix-go)\n* [rubyist](https://github.com/rubyist/circuitbreaker)\n* [sony/gobreaker](https://github.com/sony/gobreaker)\n* [handy/breaker](https://github.com/streadway/handy/tree/master/breaker)\n* [iand-circuit](\"github.com/iand/circuit\")\n\n```\n\u003e make bench\ncd benchmarking \u0026\u0026 go test -v -benchmem -run=^$ -bench=. . 2\u003e /dev/null\ngoos: darwin\ngoarch: amd64\npkg: github.com/cep21/circuit/benchmarking\nBenchmarkCiruits/cep21-circuit/Hystrix/passing/1-8       \t 2000000\t       896 ns/op\t     192 B/op\t       4 allocs/op\nBenchmarkCiruits/cep21-circuit/Hystrix/passing/75-8      \t 3000000\t       500 ns/op\t     192 B/op\t       4 allocs/op\nBenchmarkCiruits/cep21-circuit/Hystrix/failing/1-8       \t10000000\t       108 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/Hystrix/failing/75-8      \t20000000\t        82.5 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/Minimal/passing/1-8       \t10000000\t       165 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/Minimal/passing/75-8      \t20000000\t        87.7 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/Minimal/failing/1-8       \t20000000\t        64.4 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/Minimal/failing/75-8      \t100000000\t        19.6 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/cep21-circuit/UseGo/passing/1-8         \t 1000000\t      1300 ns/op\t     256 B/op\t       5 allocs/op\nBenchmarkCiruits/cep21-circuit/UseGo/passing/75-8        \t 5000000\t       374 ns/op\t     256 B/op\t       5 allocs/op\nBenchmarkCiruits/cep21-circuit/UseGo/failing/1-8         \t 1000000\t      1348 ns/op\t     256 B/op\t       5 allocs/op\nBenchmarkCiruits/cep21-circuit/UseGo/failing/75-8        \t 5000000\t       372 ns/op\t     256 B/op\t       5 allocs/op\nBenchmarkCiruits/GoHystrix/DefaultConfig/passing/1-8     \t  200000\t      8146 ns/op\t    1001 B/op\t      18 allocs/op\nBenchmarkCiruits/GoHystrix/DefaultConfig/passing/75-8    \t  500000\t      2498 ns/op\t     990 B/op\t      20 allocs/op\nBenchmarkCiruits/GoHystrix/DefaultConfig/failing/1-8     \t  200000\t      6299 ns/op\t    1020 B/op\t      19 allocs/op\nBenchmarkCiruits/GoHystrix/DefaultConfig/failing/75-8    \t 1000000\t      1582 ns/op\t    1003 B/op\t      20 allocs/op\nBenchmarkCiruits/rubyist/Threshold-10/passing/1-8        \t 1000000\t      1834 ns/op\t     332 B/op\t       5 allocs/op\nBenchmarkCiruits/rubyist/Threshold-10/passing/75-8       \t 2000000\t       849 ns/op\t     309 B/op\t       4 allocs/op\nBenchmarkCiruits/rubyist/Threshold-10/failing/1-8        \t20000000\t       114 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/rubyist/Threshold-10/failing/75-8       \t 5000000\t       302 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/gobreaker/Default/passing/1-8           \t10000000\t       202 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/gobreaker/Default/passing/75-8          \t 2000000\t       698 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/gobreaker/Default/failing/1-8           \t20000000\t        90.6 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/gobreaker/Default/failing/75-8          \t 5000000\t       346 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/handy/Default/passing/1-8               \t 2000000\t      1075 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/handy/Default/passing/75-8              \t 1000000\t      1795 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/handy/Default/failing/1-8               \t 1000000\t      1272 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/handy/Default/failing/75-8              \t 1000000\t      1686 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/iand_circuit/Default/passing/1-8        \t10000000\t       119 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/iand_circuit/Default/passing/75-8       \t 5000000\t       349 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/iand_circuit/Default/failing/1-8        \t100000000\t        20.4 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/iand_circuit/Default/failing/75-8       \t300000000\t         5.46 ns/op\t       0 B/op\t       0 allocs/op\nPASS\nok      github.com/cep21/circuit/benchmarking   59.518s\n```\n\nLimiting to just high concurrency passing circuits (the common case).\n\n```\nBenchmarkCiruits/cep21-circuit/Minimal/passing/75-8      \t20000000\t        87.7 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/GoHystrix/DefaultConfig/passing/75-8    \t  500000\t      2498 ns/op\t     990 B/op\t      20 allocs/op\nBenchmarkCiruits/rubyist/Threshold-10/passing/75-8       \t 2000000\t       849 ns/op\t     309 B/op\t       4 allocs/op\nBenchmarkCiruits/gobreaker/Default/passing/75-8          \t 2000000\t       698 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/handy/Default/passing/75-8              \t 1000000\t      1795 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkCiruits/iand_circuit/Default/passing/75-8       \t 5000000\t       349 ns/op\t       0 B/op\t       0 allocs/op\n```\n\n# [Development](https://github.com/cep21/circuit/blob/master/Makefile)\n\nMake sure your tests pass with `go test` and your lints pass with `golangci-lint run`.\n\n# [Example](https://github.com/cep21/circuit/blob/master/example/main.go)\n\nYou can run an example set of circuits inside the /example directory\n\n```bash\ngo run example/main.go\n```\n\nThe output looks something like this:\n\n```bash\ngo run example/main.go\n2017/12/19 15:24:42 Serving on socket :8123\n2017/12/19 15:24:42 To view the stream, execute:\n2017/12/19 15:24:42   curl http://localhost:8123/hystrix.stream\n2017/12/19 15:24:42\n2017/12/19 15:24:42 To view expvar metrics, visit expvar in your browser\n2017/12/19 15:24:42   http://localhost:8123/debug/vars\n2017/12/19 15:24:42\n2017/12/19 15:24:42 To view a dashboard, follow the instructions at https://github.com/Netflix/Hystrix/wiki/Dashboard#run-via-gradle\n2017/12/19 15:24:42   git clone git@github.com:Netflix/Hystrix.git\n2017/12/19 15:24:42   cd Hystrix/hystrix-dashboard\n2017/12/19 15:24:42   ../gradlew jettyRun\n2017/12/19 15:24:42\n2017/12/19 15:24:42 Then, add the stream http://localhost:8123/hystrix.stream\n```\n\nIf you load the Hystrix dasbhoard (following the above instructions), you should see metrics for all the example circuits.\n\n[![dashboard](https://cep21.github.io/circuit/imgs/hystrix_ui.png)](https://cep21.github.io/hystrix/imgs/hystrix_ui.png)\n","funding_links":[],"categories":["开源类库","Utilities","Go","Open source library","公用事业公司","实用工具","工具库","工具库`可以提升效率的通用代码库和工具`","Utility"],"sub_categories":["限流器","Utility/Miscellaneous","Fail injection","HTTP Clients","Current Limiter","实用程序/Miscellaneous","Advanced Console UIs","交流","查询语"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcep21%2Fcircuit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcep21%2Fcircuit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcep21%2Fcircuit/lists"}