func newConfiguredStorage(newLog spec.Log, storageType, storagePrefix, storageAddr string) (spec.Storage, error) { var newStorage spec.Storage var err error switch storageType { case "redis": newStorageConfig := redis.DefaultStorageConfigWithAddr(storageAddr) newStorageConfig.BackoffFactory = func() spec.Backoff { return backoff.NewExponentialBackOff() } newStorageConfig.Instrumentation, err = newPrometheusInstrumentation([]string{"Feature", "Storage", "Redis"}) if err != nil { return nil, maskAny(err) } newStorageConfig.Log = newLog newStorageConfig.Prefix = storagePrefix newStorage, err = redis.NewStorage(newStorageConfig) if err != nil { return nil, maskAny(err) } case "memory": newStorage, err = memory.NewStorage(memory.DefaultStorageConfig()) if err != nil { return nil, maskAny(err) } default: return nil, maskAnyf(invalidStorageFlagError, "%s", storageType) } return newStorage, nil }
// NewStorage creates a new configured memory storage object. Therefore it // manages an in-memory redis instance which can be shut down using the // configured closer. This is used for local development. func NewStorage(config StorageConfig) (spec.Storage, error) { addrChan := make(chan string, 1) closer := make(chan struct{}, 1) redisAddr := "" go func() { s, err := miniredis.Run() if err != nil { panic(err) } addrChan <- s.Addr() <-closer s.Close() }() select { case <-time.After(1 * time.Second): panic("starting miniredis timed out") case addr := <-addrChan: redisAddr = addr } newRedisStorageConfig := redis.DefaultStorageConfigWithAddr(redisAddr) newRedisStorageConfig.BackoffFactory = func() spec.Backoff { return backoff.NewExponentialBackOff() } newRedisStorage, err := redis.NewStorage(newRedisStorageConfig) if err != nil { return nil, maskAny(err) } newStorage := &storage{ StorageConfig: config, Closer: closer, ID: id.MustNewID(), RedisStorage: newRedisStorage, ShutdownOnce: sync.Once{}, Type: ObjectType, } return newStorage, nil }