は英語の -ity、-ism、-ization に対応します。
1、Webプログラミング、要求は、複数のゴルーチン間のデータの相互作用に対応します。
2、タイムアウト制御、制御非同期リクエストタイムアウト
3、コンテキスト制御、リクエストの流れを追跡
Golangのコンテキスト
Golangのコンテキスト
// コンテキスト情報を要求する
context
// 役割:複数のgouroutineとリクエストドメインのデータ、キャンセルシグナル、デッドライン、その他の関連する操作の間で、1つのリクエストの処理を単純化するために使われる。
type Context interface {
// 締め切りを設定する
// deadline : その時点で、コンテキストは自動的にキャンセルリクエストを開始する。
// ok == false は期限が設定されていないことを意味し、キャンセルする必要がある場合はキャンセル関数を呼び出す必要がある。
Deadline() (deadline time.Time, ok bool)
// struct型の読み取り専用チャンを返す{},
// goroutineの中で、メソッドが返すchanを読むことができれば、それは親コンテキストがキャンセル要求を開始したことを意味し、Done()メソッドを通してこのシグナルを受け取ったら、クリーンアップを行う必要がある。
// その後、ゴルーチンを終了してリソースを解放し、Err()メソッドがコンテキストがキャンセルされた理由を示すエラーを返す。
Done() <-chan struct{}
//どのようなコンテキストがキャンセルされたので、エラーのキャンセルの原因を返す
Err() error
//Contextにバインドされた値を取得するのは値のペアで、キーを通して対応する値を取得できる。
Value(key interface{}) interface{}
}
Context
// 親Contextをパラメータとして渡し、子ContextとContextをキャンセルするcancel関数を返す。
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
// WithCannelと同じように、もう1つ期限パラメータを渡す。つまり、この時点でContextは自動的にキャンセルされる。
func WithDeadline(parent Context, deadline time.Time)(Context,CancelFunc)
// WithDeadlineも基本的には同じで、自動キャンセルされた後どれくらいの時間が経てば
func WithTimeout(parent Context,timeout time.Duration)(Context,CancelFunc)
// データを値のペアにバインドするContextを生成することで、バインドされたデータをContextを通して渡すことができる。.Valueメソッドへのアクセス
func WithValue(parent Context, key ,val interface{}) Context
Golangのコンテキスト
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (*emptyCtx) Done() <-chan struct{} {
return nil
}
func (*emptyCtx) Err() error {
return nil
}
func (*emptyCtx) Value(key interface{}) interface{} {
return nil
}
func (e *emptyCtx) String() string {
switch e {
case background:
return "context.Background"
case todo:
return "context.TODO"
}
return "unknown empty Context"
}
Golangのコンテキスト
// A valueCtx carries a key-value pair. It implements Value for that key and
// delegates all other calls to the embedded Context.
type valueCtx struct {
Context
key, val interface{}
}
Golangのコンテキスト
// A cancelCtx can be canceled. When canceled, it also cancels any children
// that implement canceler.
type cancelCtx struct {
Context
mu sync.Mutex // protects following fields
done chan struct{} // created lazily, closed by first cancel call
children map[canceler]struct{} // set to nil by the first cancel call
err error // set to non-nil by the first cancel call
}
Golangのコンテキスト
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
// implement Done and Err. It implements cancel by stopping its timer then
// delegating to cancelCtx.cancel.
type timerCtx struct {
cancelCtx
timer *time.Timer // Under cancelCtx.mu.
deadline time.Time
}
Golangのコンテキスト
Golangのコンテキスト
// with_value
//
func with_value() {
// ルートコンテキストを宣言する
ctx, cancel := context.WithCancel(context.Background())
valueCtx := context.WithValue(ctx, "key", "add value")
go watch(valueCtx)
time.Sleep(5 * time.Second)
cancel()
time.Sleep(1 * time.Second)
}
func watch(ctx context.Context) {
fmt.Println("go watch")
for {
select {
case <-ctx.Done():
// コンテキストはキャンセルされる
fmt.Println(ctx.Value("key"), "is cancel")
time.Sleep(1 * time.Second)
default:
fmt.Println(ctx.Value("key"), "int goroutine")
time.Sleep(1 * time.Second)
}
}
}
Golangのコンテキスト
// with_deadtime
// 締め切り
func with_deadtime() {
dt := time.Now().Add(3 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), dt)
defer cancel()
go func(ctx context.Context) {
for {
select {
case <-time.After(2 * time.Second):
fmt.Println("期限に達した")
case <-ctx.Done():
fmt.Println("コンテキストキャンセル")
return
}
}
}(ctx)
time.Sleep(5 * time.Second)
}
Golangのコンテキスト
// with_timeout
//
func with_timeout() {
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
fmt.Println("with_timeout start")
var wg sync.WaitGroup
wg.Add(1)
go work(ctx, &wg)
wg.Wait()
fmt.Println("with_timeout end")
}
func work(ctx context.Context, wg *sync.WaitGroup) error {
defer wg.Done()
for i := 0; i < 1000; i++ {
select {
case <-time.After(1 * time.Second):
fmt.Println("Golangのコンテキスト, i)
case <-ctx.Done():
fmt.Println("Cancel context", i)
return ctx.Err()
}
}
return nil
}
、同時リクエストのタイムアウトは、すべてのリクエストをキャンセルします。
func task1() int {
time.Sleep(3 * time.Second)
return 1
}
func task2() int {
time.Sleep(2 * time.Second)
return 2
}
func task3() int {
time.Sleep(2 * time.Second)
return 3
}
// with_url
// あるリクエストがトリガーとなって3つのタスクが同時に完了し、1回のタイムアウトでそれらすべてがキャンセルされる。
// 1Golangのコンテキスト
// 2Golangのコンテキスト
func with_url() {
var res, sum int
// Golangのコンテキスト
sucess := make(chan int)
// 各タスクの結果を保存する
resChan := make(chan int, 3)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
// の起動後にすべてのタスクが完了するように同期を使う。
var wg sync.WaitGroup
wg.Add(3)
go func() {
resChan <- task1()
wg.Done()
}()
go func() {
resChan <- task2()
wg.Done()
}()
go func() {
resChan <- task3()
wg.Done()
}()
go func() {
for {
select {
case res = <-resChan:
sum += res
fmt.Println("add", res)
case <-sucess:
fmt.Println("全てのタスクが完了した後の結果", sum)
// wg.Done()
return
case <-ctx.Done():
fmt.Println("タイムアウト後の結果 ", sum)
// wg.Done()
return
}
}
}()
wg.Wait()
// タスクが完了したことを示す
sucess <- 1
}
func main() {
with_url()
}





