mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-22 04:36:02 +03:00
Add deadline.md links
- Update example using assert - Fix typo on circuit-breaker.md
This commit is contained in:
parent
450bb1c95d
commit
9001fb9e96
@ -12,7 +12,7 @@ document.
|
|||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
Below is the implementation of a very simple circuit breaker to illustrate the purpose
|
Below is the implementation of a very simple circuit breaker to illustrate the purpose
|
||||||
of the circuit breaker design pattern ,Only considering Open/Closed
|
of the circuit breaker design pattern, only considering Open/Closed
|
||||||
|
|
||||||
### Operation Counter
|
### Operation Counter
|
||||||
|
|
||||||
|
93
stability/deadline.md
Normal file
93
stability/deadline.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# Deadline Pattern
|
||||||
|
|
||||||
|
Package deadline implements the deadline (also known as "timeout") resiliency pattern for Go.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
Below is the implementation of a very simple deadline to illustrate the purpose
|
||||||
|
of the deadline design pattern.
|
||||||
|
|
||||||
|
### Deadline Constructor
|
||||||
|
|
||||||
|
`Deadline` is a simple struct that implements timeout duration checking for maximum execution time.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package deadline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrTimedOut is the error returned from Run when the deadline expires.
|
||||||
|
var ErrTimedOut = errors.New("timed out waiting for function to finish")
|
||||||
|
|
||||||
|
// Deadline implements the deadline/timeout resiliency pattern.
|
||||||
|
type Deadline struct {
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// New constructs a new Deadline with the given timeout.
|
||||||
|
func New(timeout time.Duration) *Deadline {
|
||||||
|
return &Deadline{
|
||||||
|
timeout: timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deadline Implementation
|
||||||
|
|
||||||
|
`Run` runs the given function, passing it a stopper channel. If the deadline passes before the function finishes executing, `Run` returns `ErrTimeOut` to the caller and closes the stopper channel so that the work function can attempt to exit gracefully.
|
||||||
|
|
||||||
|
It does not (and cannot) simply kill the running function, so if it doesn't respect the stopper channel then it may keep running after the deadline passes. If the function finishes before the deadline, then the return value of the function is returned from `Run`.
|
||||||
|
|
||||||
|
|
||||||
|
**Note:** Deadline can be replaced by Context, check the [Related Content](#related-contents).
|
||||||
|
```go
|
||||||
|
func (d *Deadline) Run(work func(<-chan struct{}) error) error {
|
||||||
|
result := make(chan error)
|
||||||
|
stopper := make(chan struct{})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
value := work(stopper)
|
||||||
|
select {
|
||||||
|
case result <- value:
|
||||||
|
case <-stopper:
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case ret := <-result:
|
||||||
|
return ret
|
||||||
|
case <-time.After(d.timeout):
|
||||||
|
close(stopper)
|
||||||
|
return ErrTimedOut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deadline Usage
|
||||||
|
```go
|
||||||
|
func ExampleDeadline() {
|
||||||
|
dl := New(1 * time.Second)
|
||||||
|
|
||||||
|
err := dl.Run(func(stopper <-chan struct{}) error {
|
||||||
|
// do something possibly slow
|
||||||
|
// check stopper function and give up if timed out
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
switch err {
|
||||||
|
case ErrTimedOut:
|
||||||
|
// execution took too long, oops
|
||||||
|
default:
|
||||||
|
// some other error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Related Contents
|
||||||
|
|
||||||
|
- [Deadline in Golang using Context](https://blog.golang.org/context)
|
||||||
|
|
||||||
|
- [Example using Context](https://golang.org/src/context/example_test.go)
|
@ -6,6 +6,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func assertEqual(t *testing.T, a interface{}, b interface{}) {
|
||||||
|
if a != b {
|
||||||
|
t.Fatalf("%s != %s", a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func takesFiveMillis(stopper <-chan struct{}) error {
|
func takesFiveMillis(stopper <-chan struct{}) error {
|
||||||
time.Sleep(5 * time.Millisecond)
|
time.Sleep(5 * time.Millisecond)
|
||||||
return nil
|
return nil
|
||||||
@ -27,12 +33,12 @@ func TestDeadline(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dl.Run(takesTwentyMillis); err != ErrTimedOut {
|
if err := dl.Run(takesTwentyMillis); err != nil {
|
||||||
t.Error(err)
|
assertEqual(t, err, ErrTimedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dl.Run(returnsError); err.Error() != "foo" {
|
if err := dl.Run(returnsError); err != nil {
|
||||||
t.Error(err)
|
assertEqual(t, err.Error(), "foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
Loading…
Reference in New Issue
Block a user