Skip to content

Instantly share code, notes, and snippets.

@hamakn
Created December 14, 2017 02:00
Show Gist options
  • Save hamakn/8b1ac4e0b66f09dc837df6a2fc2d2184 to your computer and use it in GitHub Desktop.
Save hamakn/8b1ac4e0b66f09dc837df6a2fc2d2184 to your computer and use it in GitHub Desktop.
Cloud Datastore(Raceで失敗するようなやつ)
// Raceで失敗するようなやつ
func TestExampleDataStore3(t *testing.T) {
testWithAEInstance(t, true, func(inst *aetest.Instance) {
req, err := (*inst).NewRequest("GET", "/", nil)
require.Nil(t, err)
ctx := appengine.NewContext(req)
// 1. Point入れる
stringID := "this_is_point_key"
now := time.Now()
p := point.Point{
ID: stringID,
UserID: "1",
ExpiredAt: now,
IsUsed: false,
CreatedAt: now,
UpdatedAt: now,
}
// Put
k := datastore.NewKey(ctx, "Point", stringID, 0, nil)
_, err = datastore.Put(ctx, k, &p)
require.Nil(t, err)
done := make(chan error)
go func() {
// 2. goroutineで、PointをGetして、2秒待って、PointをPutする
err2outer := datastore.RunInTransaction(ctx, func(tx netcontext.Context) error {
p2 := point.Point{}
datastore.Get(tx, k, &p2)
fmt.Println("==(in groutine)== Show p2")
fmt.Println(p2)
time.Sleep(2 * time.Second)
p2.IsUsed = true
_, err2 := datastore.Put(tx, k, &p2)
if err2 != nil {
return err2
}
return nil
}, &datastore.TransactionOptions{Attempts: 1})
done <- err2outer
}()
// 3. 1秒待って、PointをGetして、PointをPutする
err3outer := datastore.RunInTransaction(ctx, func(tx netcontext.Context) error {
time.Sleep(1 * time.Second)
p3 := point.Point{}
datastore.Get(tx, k, &p3)
fmt.Println("== Show p3")
fmt.Println(p3)
p3.IsUsed = true
_, err3 := datastore.Put(tx, k, &p3)
if err3 != nil {
return err3
}
return nil
}, &datastore.TransactionOptions{Attempts: 1})
// 3.は成功し、2.は失敗する
fmt.Println("== err3")
fmt.Println(err3outer)
select {
case err := <-done:
fmt.Println("== err2")
fmt.Println(err)
return
}
})
}
// =>
// % go test ./src/****/test/... -v --run TestExampleDataStore3
// === RUN TestExampleDataStore3
// WARNING 2017-12-13 08:04:04,081 application_configuration.py:167] The Managed VMs runtime is deprecated, please consider migrating your application to use the Flexible runtime. See https://cloud.google.com/appengine/docs/flexible/python/migrating for more details.
// INFO 2017-12-13 08:04:04,081 devappserver2.py:105] Skipping SDK update check.
// WARNING 2017-12-13 08:04:04,082 devappserver2.py:121] DEFAULT_VERSION_HOSTNAME will not be set correctly with --port=0
// WARNING 2017-12-13 08:04:04,136 simple_search_stub.py:1174] Could not read search indexes from /var/folders/qx/58dtxr9j4mv6k26s0x49w0whzmn1qb/T/appengine.testapp.katsunori.kawaguchi/search_indexes
// INFO 2017-12-13 08:04:04,139 api_server.py:300] Starting API server at: http://localhost:64041
// INFO 2017-12-13 08:04:05,740 dispatcher.py:251] Starting module "default" running at: http://localhost:64042
// INFO 2017-12-13 08:04:05,743 admin_server.py:116] Starting admin server at: http://localhost:64046
// ==(in groutine)== Show p2
// { 1 2017-12-13 08:04:05.743314 +0000 UTC false 2017-12-13 08:04:05.743314 +0000 UTC 2017-12-13 08:04:05.743314 +0000 UTC}
// == Show p3
// { 1 2017-12-13 08:04:05.743314 +0000 UTC false 2017-12-13 08:04:05.743314 +0000 UTC 2017-12-13 08:04:05.743314 +0000 UTC}
// == err3
// <nil>
// == err2
// datastore: concurrent transaction
// --- PASS: TestExampleDataStore3 (7.37s)
// PASS
// ok github.com/****/****/src/****/test 7.391s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment