来自 appengine aetest 的不一致行为

我正在尝试测试一个函数,该函数应该从数据存储中获取某种类型的所有对象。


在测试中,我似乎必须插入睡眠才能使查询找到所有保存的项目。


下面的代码是一个可重现的示例。第一个日志跟踪是从 sleep 行被注释掉时开始的,第二个是在 sleep 被取消注释时。注意长度:0 和长度:3


我假设这是一个最终的一致性问题,如果我坚持几个对象并立即查询它们,就会在生产中出现这种问题。但是在生产中,这些项目早就被保留了。由于这种情况只出现在我的测试中,我是否打算做一些事情来强制数据存储等待它完全保存项目后再继续?


我尝试将测试保存在事务中,但出现“事务中只允许祖先查询”错误。


type Thing struct {

  Str1 string

  Str2 string

}


func (thing Thing) Save(c appengine.Context) error {

  k := datastore.NewKey(c, "Thing", thing.Str1 + "_" + thing.Str2, 0, nil)

  if _, err := datastore.Put(c, k, &thing); err != nil {

    return err

  }

  return nil

}


func GetThings(c appengine.Context) ([]Thing, error) {

  var things []Thing

  q := datastore.NewQuery("Thing").

      Filter("Str1=", "thing")

  _, err := q.GetAll(c, &things)

  if err != nil {

    return nil, err

  }

  return things, nil

}




func TestGetThings(t *testing.T) {

  c, _ := aetest.NewContext(nil)

  defer c.Close()

  thing1 := Thing{"thing", "1"}

  thing2 := Thing{"thing", "2"}

  thing3 := Thing{"thing", "3"}

  thing1.Save(c)

  thing2.Save(c)

  thing3.Save(c)


//  time.Sleep(2000 * time.Millisecond)


  things, err := GetThings(c)

  if err != nil {

    t.Fatal(err)

  }

  t.Log("length:" + strconv.Itoa(len(things)))

}

sleep 注释掉时的日志


C:\Users\XXXX>goapp test thing -test.v


2014/09/23 21:24:05 appengine:不在 devappserver2 下运行;使用一些默认配置


=== 运行 TestGetThings


INFO 2014-09-23 21:24:07,328 devappserver2.py:725] 跳过 SDK 更新检查。


警告 2014-09-23 21:24:07,328 devappserver2.py:741] DEFAULT_VERSION_HOSTNAME 将无法使用 --port=0 正确设置


警告 2014-09-23 21:24:07,351 api_server.py:383] 无法初始化图像 API;您可能缺少 Python“PIL”模块。


INFO 2014-09-23 21:24:07,365 api_server.py:171] 在以下位置启动 API 服务器: http://localhost:50153


INFO 2014-09-23 21:24:07,371 dispatcher.py:183] 启动模块“默认”运行于: http://localhost:50154


INFO 2014-09-23 21:24:07,377 admin_server.py:117] 在以下位置启动管理服务器: http://localhost:50155


INFO 2014-09-23 21:24:08,378 api_server.py:583] 应用所有待处理的事务并保存数据存储


INFO 2014-09-23 21:24:08,388 api_server.py:586] 保存搜索索引---通过:TestGetThings(4.60 秒)


thing_test.go:87: 长度:0


经过


好的 4.729s


侃侃无极
浏览 194回答 2
2回答

Smart猫小萌

要回答我自己的问题,解决方案是在创建 aetest.NewContext 时使用 Options 参数。c, _ := aetest.NewContext(&aetest.Options{"", true})Options 结构中的第二项是名为 StronglyConsistentDatastore 的布尔值。

幕布斯7119047

您正在遇到最终一致性的情况。您可以在上一个链接或GoLang 概述中阅读相关内容。您需要做出选择,是否值得更快地写入数据。如果您在放置数据后立即需要数据,则需要执行祖先查询,这会减慢写入速度,但会立即使您的数据可用。Ancestors 还存在其他限制(例如交易),但对于您的直接关注,它将解决您的问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go