- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
过去 1 周我一直面临这个问题,我只是对此感到困惑。保持简短,简单地解释问题。
我们有一个内存模型,它存储预算等值。现在,当调用 API 时,它有一个与之关联的花费。
然后我们检查内存模型并将支出添加到现有支出中,然后检查预算,如果超出预算,我们将不再接受该模型的任何点击。对于每次调用,我们还更新了数据库,但这是一个异步操作。
一个简短的例子
api.get('/clk/:spent/:id', function(req, res) {
checkbudget(spent, id);
}
checkbudget(spent, id){
var obj = in memory model[id]
obj.spent+= spent;
obj.spent > obj.budjet // if greater.
obj.status = 11 // 11 is the stopped status
update db and rebuild model.
}
这过去工作正常,但现在对于并发请求,我们得到错误的支出,支出增加超过预算,一段时间后停止。我们用j表模拟调用,发现了这个。
据我们所知, Node 是异步的,因此当状态更新为 11 时,许多线程已经更新了事件的花费。
如何为 Node.js 提供信号量类型的逻辑,以便可变预算与模型同步
更新
db.addSpend(campaignId, spent, function(err, data) {
campaign.spent += spent;
var totalSpent = (+camp.spent) + (+camp.cpb);
if (totalSpent > camp.budget) {
logger.info('Stopping it..');
camp.status = 11; // in-memory stop
var History = [];
History.push(some data);
db.stopCamp(campId, function(err, data) {
if (err) {
logger.error('Error while stopping );
}
model.campMAP = buildCatMap(model);
model.campKeyMap = buildKeyMap(model);
db.campEventHistory(cpcHistory, false, function(err) {
if (err) {
logger.error(Error);
}
})
});
}
});
代码的 GIST 现在任何人都可以帮忙
最佳答案
问: NodeJs
中是否有semaphore
或等价物?
答: 没有。
问:那么 NodeJs
用户如何处理竞争条件?
答:理论上您不必这样做,因为javascript
中没有thread
。
在深入研究我提出的解决方案之前,我认为了解 NodeJs
的工作原理对您来说很重要。
对于 NodeJs
,它由基于事件的架构驱动。这意味着在 Node
进程中有一个包含所有“待办”事件的事件队列。
当一个事件
从队列中得到pop
时,node
将执行所有所需的代码,直到它完成了。在运行期间进行的任何 async
调用都作为其他 events
产生,并且它们在 event queue
中排队,直到听到响应是时候再次运行它们了。
问:那么我该怎么做才能确保一次只有 1 个请求可以对数据库执行更新
?
答:我相信有很多方法可以实现这一点,但其中一种更简单的方法是使用 set_timeout
API。
示例:
api.get('/clk/:spent/:id', function(req, res) {
var data = {
id: id
spending: spent
}
canProceed(data, /*functions to exec after canProceed=*/ checkbudget);
}
var canProceed = function(data, next) {
var model = in memory model[id];
if (model.is_updating) {
set_timeout(isUpdating(data, next), /*try again in=*/1000/*milliseconds*/);
}
else {
// lock is released. Proceed.
next(data.spending, data.id)
}
}
checkbudget(spent, id){
var obj = in memory model[id]
obj.is_updating = true; // Lock this model
obj.spent+= spent;
obj.spent > obj.budjet // if greater.
obj.status = 11 // 11 is the stopped status
update db and rebuild model.
obj.is_updating = false; // Unlock the model
}
注意:我在这里得到的也是伪代码,因此您可能需要稍微调整一下。
这里的想法是在您的模型中有一个标志来指示 HTTP 请求
是否可以继续执行关键代码路径。在这种情况下,您的 checkbudget
功能及其他功能。
当收到请求时,它会检查 is_updating
标志以查看它是否可以继续。如果它是 true
然后它安排一个事件,在一秒钟后被触发,这个“setTimeout”基本上变成一个事件并被放入 node
的事件队列中后期处理
当此事件稍后被触发时,再次检查。这种情况会发生,直到 is_update
标志变为 false
然后请求继续执行它的操作并且 is_update
在所有关键代码时再次设置为 false完成了。
这不是最有效的方法,但它可以完成工作,当性能出现问题时,您可以随时重新访问解决方案。
关于javascript - Node js 中的信号量等效,变量在并发请求中被修改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45755484/
我正在尝试从该网站抓取历史天气数据: http://www.hko.gov.hk/cis/dailyExtract_uc.htm?y=2016&m=1 在阅读了 AJAX 调用后,我发现请求数据的正确
我有两个 postman 请求 x,y,它们命中了两个不同的休息 api X,Y 中的端点。 x 会给我一个身份验证 token ,这是发出 y 请求所必需的。如何在请求 y 中发出请求 x ?也就是
我使用请求库通过 API 与其他服务器进行通信。但现在我需要同时发送多个(10 个或更多)POST 请求,并且只有在所有响应都正确的情况下才能进一步前进。通常语法看起来有点像这样: var optio
背景:当用户单击按钮时,其类会在class1和class2之间切换,并且此数据是通过 AJAX 提交。为了确认此数据已保存,服务器使用 js 进行响应(更新按钮 HTML)。 问题:如果用户点击按钮的
我正在将 Node.js 中的请求库用于 Google 的文本转语音 API。我想打印出正在发送的请求,如 python example . 这是我的代码: const request = requi
我经常使用requests。最近我发现还有一个 requests2 和即将到来的 requests3 虽然有一个 page其中简要提到了 requests3 中的内容,我一直无法确定 requests
我正在尝试将图像发送到我的 API,然后从中获取结果。例如,我使用发送一个 bmp 图像文件 file = {"img": open("img.bmp)} r = requests.post(url,
我发现 Google Cloud 确保移出其物理环境的任何请求都经过强制加密,请参阅(虚拟机到虚拟机标题下的第 6 页)this link Azure(和 AWS)是否遵循类似的程序?如果有人能给我指
我有一个 ASP.NET MVC 应用程序,我正在尝试在 javascript 函数中使用 jQuery 来创建一系列操作。该函数由三部分组成。 我想做的是:如果满足某些条件,那么我想执行同步 jQu
我找不到如何执行 get http 请求,所以我希望你们能帮助我。 这个想法是从外部url(例如 https://api.twitter.com/1.1/search/tweets.json?q=tw
我的应用只需要使用“READ_SMS”权限。我的问题是,在 Android 6.0 上,当我需要使用新的权限系统时,它会要求用户“发送和查看短信”。 这是我的代码: ActivityCompat.re
我的前端代码: { this.searchInput = input; }}/> 搜索 // search method: const baseUrl = 'http://localho
我有一个由 AJAX 和 C# 应用程序使用的 WCF 服务, 我需要通过 HTTP 请求 header 发送一个参数。 在我的 AJAX 上,我添加了以下内容并且它有效: $.ajax({
我正在尝试了解如何使用 promises 编写代码。请检查我的代码。这样对吗? Node.js + 请求: request(url, function (error, response, body)
如果失败(除 HTTP 200 之外的任何响应代码),我需要重试发送 GWT RPC 请求。原因很复杂,所以我不会详细说明。到目前为止,我在同一个地方处理所有请求响应,如下所示: // We
当用户单击提交按钮时,我希望提交表单。然而,就在这种情况发生之前,我希望弹出一个窗口并让他们填写一些数据。一旦他们执行此操作并关闭该子窗口,我希望发出 POST 请求。 这可能吗?如果可能的话如何?我
像 Facebook 这样的网站使用“延迟”加载 js。当你必须考虑到我有一台服务器,流量很大时。 我很感兴趣 - 哪一个更好? 当我一次执行更多 HTTP 请求时 - 页面加载速度较慢(由于限制(一
Servlet 容器是否创建 ServletRequest 和 Response 对象或 Http 对象?如果是ServletRequest,谁在调用服务方法之前将其转换为HttpServletReq
这是维基百科文章的摘录: In contrast to the GET request method where only a URL and headers are sent to the serv
我有一个循环,每次循环时都会发出 HTTP post 请求。 for(let i = 1; i console.log("succes at " + i), error => con
我是一名优秀的程序员,十分优秀!