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

開発期間数年のサービスの完成間際にcontext対応をぶち込む / introduce con...

開発期間数年のサービスの完成間際にcontext対応をぶち込む / introduce context.Context into long term project

kamakura.go #5 @ 鎌倉

acidlemon

June 22, 2019
Tweet

More Decks by acidlemon

Other Decks in Technology

Transcript

  1. 93BZͰ෼ࢄτϨʔγϯά w ૊௕ !GVKJXBSB ͷ:"1$5PLZPͷൃදͳͲͰ͓ͳ͡Έ IUUQTTQFBLFSEFDLDPNGVKJXBSBZBQDUPLZP  w ΧϠοΫͰ͸ࡢ೥͔Βෛՙࢼݧ΍ຊ൪؀ڥͷௐࠪʹ"8493BZΛ ར༻͍ͯ͠Δ

    w ૊௕͕࠷ॳʹೖΕͨࣄྫ͸1FSM͕ͩͬͨɺࠓճ͸(PϓϩμΫτ
 (PͳΒ"84͕4%,Λग़͍ͯ͠ΔͷͰࣗલͰϥΠϒϥϦ࡞ΔΈ͍ͨ ͳ͜ͱ͠ͳͯ͘΋େৎ෉͜Ε͸উͬͨͳʜʜ ϑϥάͷཱͭԻ
  2. ͜Μͳײ͡ w YSBZ$BQUVSFʹDUYͱ࣮ߦ͍ͨ͠ॲཧΛแΜͩؔ਺Λ౉͢ͱɺ $BQUVSF͕։࢝࣌ࠁͱऴྃ࣌ࠁΛDUYʹه࿥ͯ͘͠ΕΔ
 93BZ)551ΫϥΠΞϯτͳͲ͸಺෦Ͱ͜ΕΛ΍͍ͬͯΔ func criticalSection(ctx context.Context) { //this

    is an example of a subsegment xray.Capture(ctx, "GameModel.saveGame", func(ctx1 context.Context) error { var err error section.Lock() result := someLockedResource.Go() section.Unlock() xray.AddMetadata(ctx1, "ResourceResult", result) }) } IUUQTEPDTBXTBNB[PODPNKB@KQYSBZMBUFTUEFWHVJEFYSBZTELHPTVCTFHNFOUTIUNM
  3. YSBZ%#ͩ w HPSN͸42-$PNNPOͱ͍͏TRM%#ͷίϯςΩετͳ͠ϝιο υΛΠϯλϑΣʔεԽ͍ͯ͠Δ w YSBZ%#͸શ෦DUY෇͖ͰTRM%#ͷDUYϝιουΛ࣮૷͍ͯ͠Δ w ͭ·ΓΠϯλϑΣʔε͕ద߹͠ͳ͍ʜ type SQLCommon

    interface { Exec(query string, args ...interface{}) (sql.Result, error) Prepare(query string) (*sql.Stmt, error) Query(query string, args ...interface{}) (*sql.Rows, error) QueryRow(query string, args ...interface{}) *sql.Row } package xray func (db *DB) Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error) func (db *DB) Prepare(ctx context.Context, query string) (*Stmt, error) func (db *DB) Query(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) func (db *DB) QueryRow(ctx context.Context, query string, args ...interface{}) *sql.Row HPSN YSBZ
  4. ϥούʔʹ$BQUVSFΛ௥Ճ w 93BZͷ$BQUVSFΛͦΕͧΕͷϝιουͰ΍Δ w ͜ͷํࣜͰ͸HPSN͕࣮ࡍʹ࣮ߦ͢Δ42-ΛऔΓग़ͤͳ͍ͨΊɺ୅ΘΓ ʹݺͼग़͠ͷҾ਺ͱίʔϧελοΫΛه࿥ // Exec ͩΑ func

    (g *GormDB) Exec(ctx context.Context, sql string, values ...interface{}) *GormDB { if seg := xray.GetSegment(ctx); seg == nil { return g.wrap(g.db.Exec(sql, values...)) } var res *GormDB tmp := []interface{}{sql} tmp = append(tmp, values...) caller := traceCaller("Exec", tmp...) xray.Capture(ctx, g.name, func(ctx context.Context) error { g.recordSQL(ctx, caller) res = g.wrap(g.db.Exec(sql, values...)) return res.Error }) return res } 93BZະ࢖༻࣌ 93BZ࢖༻࣌
  5. த਎ w ίʔϧελοΫͱ42-ͷBSHTΛه࿥ w ه࿥෦෼͸93BZ4%,ͷxray.DB.populate()Λࢀߟʹ func traceCaller(name string, args ...interface{})

    string { pc, _, line, _ := runtime.Caller(2) f := runtime.FuncForPC(pc) return fmt.Sprintf("from %s(Line %d): %s(%s) ", f.Name(), line, name, argsString(args...)) } func (g *GormDB) recordSQL(ctx context.Context, info string) { seg := xray.GetSegment(ctx) typ := "master" if g.slave { typ = "slave" } seg.Lock() seg.Namespace = "remote" seg.GetSQL().ConnectionString = g.name seg.GetSQL().DatabaseType = typ seg.GetSQL().SanitizedQuery = info seg.Unlock() }
  6. ΫϥΠΞϯτ੾அʹΑΔDBODFM w ͦ΋ͦ΋ႈ౳ͳ࡞Γͷ"1*ʹͳ͍ͬͯΕ͹ɺαʔόʹϦΫΤετ͕དྷ ͨΒΫϥΠΞϯτʹؔ܎ͳ͘૸Γ͖ͬͨ΄͏͕Α͍ w SFRSFR8JUI$POUFYU OFX$UY Ͱࠩ͠ସ͑Ͱ͖Δ w ϦΫΤετࣗମͷλΠϜΞ΢τ͸ඞཁͳͷͰɺSFRͷDUYΛܧঝͤͣ

    ʹDPOUFYU#BDLHSPVOE Ͱ৽͍͠ίϯςΩετΛ࡞ͬͯλΠϜ Ξ΢τΛઃఆ͢Δ w 4FSWFSΛ(SBDFGVMʹTIVUEPXO͢Δͷ͸ϦΫΤετλΠϜΞ ΢τ෼͘Β͍଴ͯ͹৽͍͠ϦΫΤετड͚෇͚ͳ͍ͷͰେৎ෉
  7. ·ͱΊײ૝ w ઌԆ͹͍ͯ͠͠Δͱޙ͔ΒϦϑΝΫλϦϯά͢Δίετ͕͍͢͝ࣄʹ ͳΔͷͰͬ͞͞ͱDPOUFYUରԠͨ͠΄͏͕Α͍ w ࠓ͔Β։ൃΛ࢝ΊΔͳΒɺ࢖͍ͬͯΔ%#03.΍3FEJTΞΫηεͳ Ͳͷύοέʔδ͸DPOUFYUରԠ͍ͯ͠Δ΋ͷΛબͿ΂͖
 ٕज़બఆͷ༏ઌ౓ͱ͔ͯ͠ͳΓߴ͍ͱ͜ΖʹҐஔ͚ͮΔ΂͖  w

    ઃܭํ਑ͱͯ͠ɺ ͨͱ͑ͦΕΛ࣮૷͢Δͱ͖͸࢖ͬͯͳͯ͘΋ ϩ δοΫతʹ֎෦ͷ*0͕͋Δ΋ͷ͸DPOUFYUΛ౉͓ͯ͘͠ͱΑ͍
 ͦ͏ͳΔͱ'MVFOUEͰϩάऔΔՄೳੑ͕͋Δͱ͜Ζ͸શ෦౉ͦ͏ʜͱͳΔ͚Ͳͦ͏͍͏΋Μͩ