Skip to content

Commit a4a57a5

Browse files
author
eamon
committed
finished deadline pattern
1 parent 9bb39b3 commit a4a57a5

File tree

4 files changed

+69
-52
lines changed

4 files changed

+69
-52
lines changed

.vscode/settings.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"window.autoDetectColorScheme": false,
33
"editor.tabSize": 2,
4-
"editor.semanticTokenColorCustomizations":{
5-
"enabled": true, // enable semantic highlighting for all themes
6-
"rules": {
7-
"typeParameter": "#352cea",
8-
"type": {
9-
"foreground": "#00aa00"
10-
},
11-
"parameter":"#4c70e7",
12-
}
4+
"editor.semanticTokenColorCustomizations": {
5+
"enabled": true, // enable semantic highlighting for all themes
6+
"rules": {
7+
"typeParameter": "#352cea",
8+
"type": {
9+
"foreground": "#00aa00"
10+
},
11+
"parameter": "#4c70e7",
12+
}
1313
},
1414
"extensions.showRecommendationsOnlyOnDemand": true,
1515
"files.trimTrailingWhitespace": true,
@@ -47,9 +47,9 @@
4747
"editor.codeActionsOnSave": {
4848
"source.organizeImports": true
4949
},
50-
"fileheader.Author":"Edward",
51-
"fileheader.tpl": "/*\r\n * @Description: https://github.com/crazybber\r\n * @Author: {author}\r\n * @Date: {createTime}\r\n * @Last Modified by: {lastModifiedBy}\r\n * @Last Modified time: {updateTime}\r\n */\r\n\r\n",
52-
"fileheader.LastModifiedBy": "Edward",
53-
"peacock.color": "#5e7959"
50+
"fileheader.Author": "Edward",
51+
"fileheader.tpl": "/*\r\n * @Description: https://github.com/crazybber\r\n * @Author: {author}\r\n * @Date: {createTime}\r\n * @Last Modified by: {lastModifiedBy}\r\n * @Last Modified time: {updateTime}\r\n */\r\n\r\n",
52+
"fileheader.LastModifiedBy": "Edward",
53+
"peacock.color": "#5e7959"
5454
}
5555
//https://vscode.readthedocs.io/en/latest/getstarted/settings/

resiliency/03_deadline/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
do a thing ,until the deadline time point
44

5+
as known as timeout pattern
6+
57
which act like time.after(), but time.after() only do once.

resiliency/03_deadline/deadline.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,53 @@
33
* @Author: Edward
44
* @Date: 2020-06-05 12:43:39
55
* @Last Modified by: Edward
6-
* @Last Modified time: 2020-06-05 12:56:40
6+
* @Last Modified time: 2020-06-05 17:34:37
77
*/
88

9-
// Package deadline implements the deadline (also known as "timeout") resiliency pattern for Go.
9+
// Package deadline implements deadline (also known as "timeout") resiliency pattern for Go.
1010
package deadline
1111

1212
import (
1313
"errors"
1414
"time"
1515
)
1616

17-
// ErrTimedOut is the error returned from Run when the deadline expires.
17+
// ErrTimedOut is the error returned from Run when the Worker expires.
1818
var ErrTimedOut = errors.New("timed out waiting for function to finish")
1919

20-
// Deadline implements the deadline/timeout resiliency pattern.
21-
type Deadline struct {
20+
// Worker implements the Deadline/timeout resiliency pattern.
21+
// worker do the target job
22+
type Worker struct {
2223
timeout time.Duration
2324
action string
2425
}
2526

26-
// New constructs a new Deadline with the given timeout.
27-
func New(timeout time.Duration, sometile string) *Deadline {
28-
return &Deadline{
27+
// New create a new Worker with the given timeout.and tile
28+
func New(timeout time.Duration, someActionTitle string) *Worker {
29+
return &Worker{
2930
timeout: timeout,
31+
action: someActionTitle,
3032
}
3133
}
3234

33-
// Run runs the given function, passing it a stopper channel. If the deadline passes before
35+
// Run runs the given function, passing it a stopper channel. If the Worker passes before
3436
// the function finishes executing, Run returns ErrTimeOut to the caller and closes the stopper
3537
// channel so that the work function can attempt to exit gracefully. It does not (and cannot)
3638
// simply kill the running function, so if it doesn't respect the stopper channel then it may
37-
// keep running after the deadline passes. If the function finishes before the deadline, then
39+
// keep running after the Worker passes. If the function finishes before the Worker, then
3840
// the return value of the function is returned from Run.
39-
func (d *Deadline) Run(work func(<-chan struct{}) error) error {
40-
result := make(chan error)
41+
func (d *Worker) Run(work func(stopperSignal chan error) error) error {
4142

42-
stopper := make(chan struct{})
43+
result := make(chan error)
44+
//we can stop the work in advance
45+
stopper := make(chan error, 1)
4346

4447
go func() {
4548
value := work(stopper)
4649
select {
4750
case result <- value:
48-
case <-stopper:
51+
case stopError := <-stopper:
52+
result <- stopError
4953
}
5054
}()
5155

resiliency/03_deadline/deadline_test.go

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,75 @@ package deadline
22

33
import (
44
"errors"
5+
"fmt"
56
"testing"
67
"time"
78
)
89

9-
func takes5ms(stopper <-chan struct{}) error {
10+
func workerTakes5ms(stopper chan error) error {
11+
fmt.Println("i'm doing this job in 5ms")
1012
time.Sleep(5 * time.Millisecond)
1113
return nil
1214
}
1315

14-
func takes20ms(stopper <-chan struct{}) error {
16+
func workerTakes20ms(stopper chan error) error {
17+
fmt.Println("i'm doing this job in 20ms,so work will timeout")
1518
time.Sleep(20 * time.Millisecond)
1619
return nil
1720
}
1821

19-
func returnsError(stopper <-chan struct{}) error {
22+
func cancelWork(stopper chan error) error {
23+
fmt.Println("i'm doing this job")
24+
stopper <- errors.New("canceled job") //cancel job
25+
time.Sleep(5 * time.Millisecond)
26+
fmt.Println("job canceled")
27+
return nil
28+
}
29+
30+
func returnsError(stopper chan error) error {
31+
fmt.Println("i'm doing this job but error occurred")
2032
return errors.New("foo")
2133
}
2234

2335
func TestMultiDeadline(t *testing.T) {
24-
dl := New(10*time.Millisecond, "test multi deadline case")
2536

26-
if err := dl.Run(takes5ms); err != nil {
27-
t.Error(err)
28-
}
37+
dl := New(15*time.Millisecond, "test multi deadline case")
2938

30-
if err := dl.Run(takes20ms); err != ErrTimedOut {
39+
if err := dl.Run(workerTakes5ms); err != nil {
3140
t.Error(err)
3241
}
3342

34-
if err := dl.Run(returnsError); err.Error() != "foo" {
43+
err := dl.Run(cancelWork)
44+
45+
t.Log("cancelWork error:", err)
46+
47+
if err.Error() != "canceled job" {
3548
t.Error(err)
3649
}
3750

38-
done := make(chan struct{})
39-
err := dl.Run(func(stopper <-chan struct{}) error {
40-
<-stopper
41-
close(done)
42-
return nil
43-
})
51+
err = dl.Run(workerTakes20ms)
52+
4453
if err != ErrTimedOut {
4554
t.Error(err)
4655
}
47-
<-done
4856
}
4957

5058
func TestDeadline(t *testing.T) {
51-
dl := New(1*time.Second, "one dead line case")
5259

53-
err := dl.Run(func(stopper <-chan struct{}) error {
54-
time.Sleep(time.Second * 10)
60+
dl := New(1*time.Second, "one time deadline case worker")
61+
62+
done := make(chan error)
63+
64+
err := dl.Run(func(stopper chan error) error {
65+
fmt.Println("i am doing something here")
66+
time.Sleep(time.Second * 2)
67+
close(done)
5568
return nil
5669
})
5770

58-
switch err {
59-
case ErrTimedOut:
60-
t.Error("execution took too long, oops")
61-
default:
62-
// some other error
63-
t.Log("done")
71+
if err != ErrTimedOut {
72+
t.Error(err)
6473
}
74+
<-done
75+
6576
}

0 commit comments

Comments
 (0)