通过将键存储到会话中,加快页面加载速度,使用Go语言。

huangapple go评论87阅读模式
英文:

Loading page faster by storing keys into sessions golang

问题

我正在尝试加快加载动态页面的速度。我正在制作一个Twitter克隆作为学习任务。我遵循以下方法:

  1. 当有人发推文时,将推文存储在数据存储中,并将其保存在内存缓存中({ key.string(),json.Marshal(tweet) })。

  2. 我将推文推送到用户的主页时间线。主页时间线是一个[]*datastore.Key,它存储在用户会话中(会话会被复制到内存缓存,然后存储在数据库中)。

  3. 当用户打开自己的主页时,主页会尝试从会话中获取键,如果找不到,则进行数据存储查询。

  4. 一旦我获得了键,我就从内存缓存中获取推文(如果没有,则从数据库中获取)。

我在第3步卡住了。

在第一种情况下,我可以获取正确的信息,但是以字符串切片的形式(而不是[]*datastore.Key)。

在第二种情况下,我遇到了以下错误:
> 2016/09/03 17:23:42 http: panic serving 127.0.0.1:47104: interface
> conversion: interface is []interface {},而不是[]datastore.Key

请帮助我找出问题出在哪里,是否有更好的方法。

第一种情况:

func GetKeys(req *http.Request, vars ...string) []interface{} {
	//GetKeys - 获取键
	s, _ := GetGSession(req)
	var flashes []interface{}
	key := internalKey
	if len(vars) > 0 {
		key = vars[0]
	}

	if v, ok := s.Values[key]; ok {
		// 删除闪存并返回它。
		//	delete(s.Values, key)
		flashes = v.([]interface{})
	}
	return flashes
}

第二种情况:

//GetHTLKeys - 获取主页时间线键
func GetHTLKeys(req *http.Request, vars ...string) []datastore.Key {
	s, _ := GetGSession(req)

	var keyList []datastore.Key

	key := internalKey
	if len(vars) > 0 {
		key = vars[0]
	}

	if v, ok := s.Values[key]; ok {
		keyList = v.([]datastore.Key)
	}
	return keyList
}
英文:

I am trying to load dynamic page faster. I am making twitter clone as a learning assignment. I am following below approach

  1. When somebody tweets, store the tweet in datastore and safe the same in memcache { key.string(), json.Marshal(tweet) }

  2. I push the tweet in User home time line. The home time line is a []*datastore.Key, which is stored in user session (which get copied in memcache and then in DB).

  3. When user open her homepage, the homepage try to get the Keys from session, if not found then it make a datastore query.

  4. Once i get the keys I fetch the tweets from memcache (if not then from db)

I am stuck at step 3.

In first case I am getting the correct information but in string slices (not in []*datastore.Key).

In second case I getting this error
> 2016/09/03 17:23:42 http: panic serving 127.0.0.1:47104: interface
> conversion: interface is []interface {}, not []datastore.Key

Kindly help me where I am going wrong and is there a better way.

case 1

func GetKeys(req *http.Request, vars ...string) []interface{} {
	//GetKeys - get the keys
	s, _ := GetGSession(req)
	var flashes []interface{}
	key := internalKey
	if len(vars) > 0 {
		key = vars[0]
	}

	if v, ok := s.Values[key]; ok {
		// Drop the flashes and return it.
		//	delete(s.Values, key)
		flashes = v.([]interface{})
	}
	return flashes
}

Case2

//GetHTLKeys - get the hometimeline keys
func GetHTLKeys(req *http.Request, vars ...string) []datastore.Key {
	s, _ := GetGSession(req)

	var keyList []datastore.Key

	key := internalKey
	if len(vars) > 0 {
		key = vars[0]
	}

	if v, ok := s.Values[key]; ok {
		keyList = v.([]datastore.Key)
	}
	return keyList
}

答案1

得分: 0

你的问题是无法断言[]interface{}[]datastore.Key。这是因为它们是不同的类型。
在这种情况下,你可以将v类型断言为[]interface{},然后遍历切片并对每个元素进行类型断言。

以下是一个示例,演示了这一点(playground 版本):

type I interface {
    I()
}

type S struct{}

func (s S) I() {
    fmt.Println("S 实现了 I 接口")
}

// 模拟从会话中获取某些内容
func f(s S) interface{} {
    return []interface{}{s}
}

func main() {
    v := f(S{})

    // v2 := v.([]I) 在你的示例中会引发 panic。

    v2, ok := v.([]interface{})
    if !ok {
        // 处理值为非 []interface{} 的情况
    }
    for _, v3 := range v2 {
        v4, ok := v3.(I)
        if !ok {
            // 处理切片中存在非 I 类型的情况
        }
        v4.I() // 这里肯定是一个 I 类型
    }
}
英文:

Your issue is that you can't assert an []interface{} is a []datastore.Key. This is because they are different.
What you can do at this point, is type assert v to a []interface{} then loop through the slice and type assert each element.

Here is an example demonstrating this (playground version):

type I interface {
    I()
}

type S struct{}

func (s S) I() {
	fmt.Println("S implements the I interface")
}

// Represents you getting something out of the session
func f(s S) interface{} {
	return []interface{}{s}
}

func main() {
	v := f(S{})

	//v2 := v.([]I) would panic like in your example.

	v2, ok := v.([]interface{})
	if !ok {
		// handle having a non []interface{} as a value
	}
	for _, v3 := range v2 {
		v4, ok := v3.(I)
		if !ok {
			// handle having a non-I in the slice
		}
		v4.I() //you definitely have an I here 
	}

}

huangapple
  • 本文由 发表于 2016年9月4日 02:29:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/39310126.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定