func (cp *CachePool) startCacheService() { commandLine := cp.rowCacheConfig.GetSubprocessFlags(cp.socket) cp.cmd = exec.Command(commandLine[0], commandLine[1:]...) if err := cp.cmd.Start(); err != nil { panic(NewTabletError(ErrFatal, vtrpc.ErrorCode_INTERNAL_ERROR, "can't start memcache: %v", err)) } attempts := 0 for { c, err := cacheservice.Connect(cacheservice.Config{ Address: cp.socket, Timeout: 30 * time.Millisecond, }) if err != nil { attempts++ if attempts >= 50 { cp.cmd.Process.Kill() // Avoid zombies go cp.cmd.Wait() // FIXME(sougou): Throw proper error if we can recover log.Fatalf("Can't connect to cache service: %s", cp.socket) } time.Sleep(100 * time.Millisecond) continue } if _, err = c.Set("health", 0, 0, []byte("ok")); err != nil { panic(NewTabletError(ErrFatal, vtrpc.ErrorCode_INTERNAL_ERROR, "can't communicate with cache service: %v", err)) } c.Close() break } }
func TestRegisterFakeCacheService(t *testing.T) { Register() service, err := cs.Connect(cs.Config{}) if err != nil { t.Fatalf("got error when creating a new fake cacheservice: %v", err) } if s, ok := service.(*FakeCacheService); !ok { t.Fatalf("created service is not a fake cacheservice, cacheservice: %v", s) } }
// Open opens the pool. It launches memcache and waits till it's up. func (cp *CachePool) Open() { cp.mu.Lock() defer cp.mu.Unlock() if cp.pool != nil { panic(NewTabletError(ErrFatal, vtrpc.ErrorCode_INTERNAL_ERROR, "rowcache is already open")) } if cp.rowCacheConfig.Binary == "" { panic(NewTabletError(ErrFatal, vtrpc.ErrorCode_INTERNAL_ERROR, "rowcache binary not specified")) } cp.socket = generateFilename(cp.rowCacheConfig.Socket) cp.startCacheService() log.Infof("rowcache is enabled") f := func() (pools.Resource, error) { return cacheservice.Connect(cacheservice.Config{ Address: cp.socket, Timeout: 10 * time.Second, }) } cp.pool = pools.NewResourcePool(f, cp.capacity, cp.capacity, cp.idleTimeout) if cp.memcacheStats != nil { cp.memcacheStats.Open() } }