Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2相コミットなどの実例に見るゴルーチンとチャネルの使いどころ

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for kojiaomatsu kojiaomatsu
November 13, 2021

 2相コミットなどの実例に見るゴルーチンとチャネルの使いどころ

Avatar for kojiaomatsu

kojiaomatsu

November 13, 2021
Tweet

More Decks by kojiaomatsu

Other Decks in Technology

Transcript

  1. # 視 視 sync.WaitGroup 規 // Cloud SQL -> Datastore

    // ॲཧ201͕ऴΘͬͨ͜ͱΛ஌ΒͤΔ c1 := make(chan int) // Cloud SQL -> Datastore // ॲཧ202Ͱબ୒͞Εͨঢ়ଶΛ఻͑Δ c2 := make(chan int) // Cloud SQL -> Datastore // Prepare (err != nil ͳΒࣦഊ͍ͯ͠Δ) dbPrepareCh := make(chan error) // Datastore -> Cloud SQL // DatastoreͷτϥϯβΫγϣϯ݁Ռ dbTxResultCh := make(chan error, 1)
  2. // Datastore go func() { defer close(dsTxResultCh) begin() doSomething(101) <-c1

    doSomething(102) state := <-c2 doSomething(state) // Prepare err := <-dbPrepareCh if err != nil { dsTxResultCh <- err rollback() } else { err = commit() dsTxResultCh <- err } }() # defer 視 dbPrepareCh
  3. // Datastore go func() { ... doSomething(101) _, ok :=

    <-c1 if !ok { rollback() return } doSomething(102) state := <-c2 err := doSomething(state) if err != nil { rollback() // ϒϩοΫΛղআ͢Δඞཁ͕ग़Δ <-dbPrepareCh return } ... }() # select
  4. // Cloud SQL go func() { defer close(c1) defer close(c2)

    defer close(dbPrepareCh) begin() doSomething(201) c1 <- 0 doSomething(202) c2 <- SomeState err := doSomething(203) dbPrepareCh <- err err = <-dsTxResultCh if err != nil { commit() } else { rollback() } }() # defer dbPrepareCh Prepare dsTxResultCh Datastore
  5. # #

  6. # // 3000ඵ͔͔Δ func handle1() { for i := 0;

    i < 1000; i++ { send(i) } } // 3ඵͰऴΘΔ func handle2() { for i := 0; i < 1000; i++ { go send(i) } } func send(num int) { time.Sleep(3 * time.Second) fmt.Printf("sent %v\n", num) }
  7. # func handle() { c := make(chan int, 300) go

    func() { defer close(c) for i := 0; i < 10000; i++ { c <- i } }() var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() for { num, ok := <-c if !ok { return } send(num) } }() } wg.Wait() }
  8. # 1