Slide 1

Slide 1 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 ttlcacheͷ͕͜͜εΰ͍ - genericsɺطଘͷίʔυɺஔ͖׵͍͑ͨ -

Slide 2

Slide 2 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 ࢁԼ ࿨඙ @pyama86 'GMOϖύϘ ٕज़ج൫νʔϜ', ‘ݞॻ' => 'γχΞɾϓϦϯγύϧ', 'झຯ' => ['ώϧτϯ८Γ', 'Ωϟϯϓ', ‘ཱྀߦ’,’εϚϒϥ’], '΢ΣϒαΠτ' => [ 'life' => 'http://pyama.fun', 'stns' => 'http://stns.jp', ], ]; 2

Slide 3

Slide 3 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 Go͸ΫϥΠΞϯτΩϟογϡ͕ͨ͘͞Μ͋Δ wIUUQTHJUIVCDPNFLPHPDBDIF wIUUQTHJUIVCDPNIBTIJDPSQHPMBOHMSV wIUUQTHJUIVCDPNKFMMZEBUPSUUMDBDIF 3 IUUQTHJUIVCDPNBWFMJOPBXFTPNFHP

Slide 4

Slide 4 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 ttlcache w ػೳ͕গͳ͍γϯϓϧͳ 55-෇͖ͷΦϯϝϞϦΩϟογϡ w σϑΥϧτ͸55-͕ࣗಈԆ௕͞ΕΔ w Ϩίʔυͷ௥Ճ࣌ɺ࡟আ࣌ʹ ϑοΫ͕࣮ߦͰ͖Δ w -PBEFS΋͋ΓଟॏΫΤϦΛ཈੍Ͱ͖Δ 4 package main import ( "time" "github.com/jellydator/ttlcache" ) func main() { cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](time.Minute), ) go cache.Start() }

Slide 5

Slide 5 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 Hooks 5 cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) { tracer.Increment(item.Value(), item.ExpiresAt()) }) cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { if reason == ttlcache.EvictionReasonCapacityReached { slack.Notify(item.Value(), item.ExpiresAt()) } }) ௨஌ͨ͠ΓɺΧ΢ϯλʔΛೖΕͨΓ

Slide 6

Slide 6 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 Loader 6 Ωϟογϡ͕੾Εͨͱ͖ʹଟॏʹϩʔυ͞ΕΔ໰୊

Slide 7

Slide 7 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 Loader 7 loader := ttlcache.LoaderFunc[…](func(…, key string)) *ttlcache.Item[string, int] { return runQuery(fmt.Sprintf(`SELECT * FROM name = “%s”`, key) }) group := &singleflight.Group{} sl := ttlcache.NewSuppressedLoader[string, string](loader, group) cache := ttlcache.New[string, int]( ttlcache.WithTTL[string, int](30*time.Minute), ttlcache.WithLoader[string, int](sl), ) cache.Get(“gopher”) Ωϟογϡ͕ͳ͍ͱ͖ʹɺϩʔυ͢ΔίʔϧόοΫ

Slide 8

Slide 8 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 single fl ight.Group 8 var g singleflight.Group for i := 0; i < 3; i++ { go func(i int) { v, _, _ := g.Do("cache_key", func() (interface{}, error) { fmt.Println("Fetching from origin...") time.Sleep(2 * time.Second) return "response_data", nil }) fmt.Printf("Result for goroutine %d: %v\n", i, v) }(i) } ଟॏ࣮ߦΛҰͭͷ࣮ߦʹ·ͱΊΔ͜ͱ͕Ͱ͖Δ

Slide 9

Slide 9 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 single fl ight.Group 9 Fetching from origin... Result for goroutine 0: response_data Result for goroutine 1: response_data Result for goroutine 2: response_data ϑΣον͸ճɺ݁Ռ͸ߦ 'FUDI͸ճ͚࣮ͩߦ

Slide 10

Slide 10 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 ttlcacheͷ͕͜͜εΰ͍ wػೳ͕গͳ͍ίʔυ͕௥͍΍͍͢͠ɺ֮͑Δ͜ͱ͕͘͢ͳ͍ wΦϯϝϞϦΩϟογϡ͚ͩͳΒඞཁे෼ w3FEJTͱ૊Έ߹ΘͤΔͱ͔ͳΒଞͷύοέʔδ࢖ͬͨ΄͏͕ྑ͍ 10

Slide 11

Slide 11 text

🍉🌴🏄 GoConference’19 🏄🌴🍉 શͯͷࣄۀͰ࠾༻͠·͍ͬͯ͘·͢ !QC@SFDSVJU 11