diff --git a/resiliency/03_deadline/README.md b/resiliency/03_deadline/README.md new file mode 100644 index 0000000..f91df53 --- /dev/null +++ b/resiliency/03_deadline/README.md @@ -0,0 +1,5 @@ +# deadline pattern + +do a thing ,until the deadline time point + +which act like time.after(), but time.after() only do once. diff --git a/resiliency/03_deadline/deadline.go b/resiliency/03_deadline/deadline.go index c97fd86..aab0475 100644 --- a/resiliency/03_deadline/deadline.go +++ b/resiliency/03_deadline/deadline.go @@ -1,3 +1,11 @@ +/* + * @Description: https://github.com/crazybber + * @Author: Edward + * @Date: 2020-06-05 12:43:39 + * @Last Modified by: Edward + * @Last Modified time: 2020-06-05 12:56:40 + */ + // Package deadline implements the deadline (also known as "timeout") resiliency pattern for Go. package deadline @@ -12,10 +20,11 @@ var ErrTimedOut = errors.New("timed out waiting for function to finish") // Deadline implements the deadline/timeout resiliency pattern. type Deadline struct { timeout time.Duration + action string } // New constructs a new Deadline with the given timeout. -func New(timeout time.Duration) *Deadline { +func New(timeout time.Duration, sometile string) *Deadline { return &Deadline{ timeout: timeout, } @@ -29,6 +38,7 @@ func New(timeout time.Duration) *Deadline { // the return value of the function is returned from Run. func (d *Deadline) Run(work func(<-chan struct{}) error) error { result := make(chan error) + stopper := make(chan struct{}) go func() { @@ -39,6 +49,8 @@ func (d *Deadline) Run(work func(<-chan struct{}) error) error { } }() + //handle result + select { case ret := <-result: return ret diff --git a/resiliency/03_deadline/deadline_test.go b/resiliency/03_deadline/deadline_test.go index 6939f52..d3934bd 100644 --- a/resiliency/03_deadline/deadline_test.go +++ b/resiliency/03_deadline/deadline_test.go @@ -6,12 +6,12 @@ import ( "time" ) -func takesFiveMillis(stopper <-chan struct{}) error { +func takes5ms(stopper <-chan struct{}) error { time.Sleep(5 * time.Millisecond) return nil } -func takesTwentyMillis(stopper <-chan struct{}) error { +func takes20ms(stopper <-chan struct{}) error { time.Sleep(20 * time.Millisecond) return nil } @@ -20,14 +20,14 @@ func returnsError(stopper <-chan struct{}) error { return errors.New("foo") } -func TestDeadline(t *testing.T) { - dl := New(10 * time.Millisecond) +func TestMultiDeadline(t *testing.T) { + dl := New(10*time.Millisecond, "test multi deadline case") - if err := dl.Run(takesFiveMillis); err != nil { + if err := dl.Run(takes5ms); err != nil { t.Error(err) } - if err := dl.Run(takesTwentyMillis); err != ErrTimedOut { + if err := dl.Run(takes20ms); err != ErrTimedOut { t.Error(err) } @@ -47,19 +47,19 @@ func TestDeadline(t *testing.T) { <-done } -func ExampleDeadline() { - dl := New(1 * time.Second) +func TestDeadline(t *testing.T) { + dl := New(1*time.Second, "one dead line case") err := dl.Run(func(stopper <-chan struct{}) error { - // do something possibly slow - // check stopper function and give up if timed out + time.Sleep(time.Second * 10) return nil }) switch err { case ErrTimedOut: - // execution took too long, oops + t.Error("execution took too long, oops") default: // some other error + t.Log("done") } }