谷歌云数据存储:多次保存调用仅创建一个实体



我有一个带有http触发器的谷歌云函数,我想用它来将信息保存到数据存储中。

当我向其发送信息时,第一个请求将起作用并在数据存储中创建实体,但后续请求不会。

这是我的函数:


const Datastore = require('@google-cloud/datastore')
const datastore = new Datastore({
projectId: 'XXXX'
})
const myKey = datastore.key({namespace: 'mynamespace', path: ['mypath']})
exports.metrics = async (req, res) => {
let type = req.body.type
let user = req.body.user
let date = req.body.date || new Date().toISOString()
await datastore
.upsert({
key: myKey,
data: {
type,
user,
date
}
})
.then(response => {
res.status(200).send(response)
})
.catch(err => {
res.status(400).send(err)
})
}

我没有收到错误。我总是得到 200 的回复,但回复各不相同。 对于有效的请求,mutationResults 包含有关密钥的信息。在那些不起作用的请求中,突变结果键为空。

那么为什么只有一些请求有效呢?

你的代码对我有用...

需要注意的是:对单个(数据存储(实体的更新过去限制为 5/秒 (!?(,但这似乎已经放松|改进,但仍然受到限制:

https://cloud.google.com/datastore/docs/best-practices#updates_to_an_entity

我假设您使用的是"数据存储"(而不是"Firestore Native"(模式,因为您使用的是命名空间;代码不会出错,但在本机模式下不起作用。

注意如果要部署为云函数,则在更新数据存储时无需提供具有project值的对象,因为此值由环境提供。

注意要记住的另一件事是,由于key每个实例的全局常量,因此如果扩展到>1 Cloud Functions 实例,您将能够生成多个实体

/* jshint esversion: 10 */
/* globals exports,require */
const { Datastore } = require("@google-cloud/datastore");
const datastore = new Datastore();
const key = datastore.key({
namespace: "ns",
path: ["path"]
});
console.log(`${key}`);
exports.metrics = async (req, res) => {
let type = req.body.type;
let user = req.body.user;
let date = req.body.date || new Date().toISOString();
await datastore.upsert({
key: key,
data: {
type,
user,
date
}
}).then(response => {
res.status(200).send(response);
}).catch(err => {
res.status(400).send(err);
});
};

package.json

{
"name": "62718657",
"version": "0.0.1",
"dependencies": {
"@google-cloud/datastore": "6.0.0"
}
}

和:

gcloud functions deploy metrics 
--allow-unauthenticated 
--entry-point=metrics 
--trigger-http 
--project=${PROJECT} 
--region=us-central1 
--runtime=nodejs10

我(似乎只(在函数|更新插入成功时得到 200 秒。

我可以通过以下方式强制更新插入争用:

ENDPOINT=$(
gcloud functions describe metrics 
--project=${PROJECT} 
--format="value(httpsTrigger.url)")
for t in {1..100}
do
printf "%sn" $(curl --silent ${ENDPOINT})
done

这将产生:

{
"code":10,
"details":"too much contention on these datastore entities. please try again.",
"metadata":{
"internalRepr":{},
"options":{}
}
}

和:

gcloud functions logs read --project=${PROJECT}
LEVEL  NAME     EXECUTION_ID  TIME_UTC                 LOG
metrics  gn3g6prcri96  2020-07-07 17:38:08.736  undefined
metrics  ogcineo00ryu  2020-07-07 17:38:08.743  failure: Error: 10 ABORTED: too much contention on these datastore entities. please try again.
metrics  ogcineo00ryu  2020-07-07 17:38:08.743  undefined
D      metrics  ogcineo00ryu  2020-07-07 17:38:08.745  Function execution took 8083 ms, finished with status code: 400

最新更新