javascript - Semaphore equivalent in Node js , variable getting modified in concurrent request? -
i facing issue past 1 week , confused this. keeping short , simple explain problem.
we have in memory model stores values budget etc.now when call made api has spent associated it.
we check in memory model , add spent existing spend , check budget , if exceeds donot accept more clicks of model. each call udpate db async operation.
a short example
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 stopped status update db , rebuild model. }
this used work fine concurrent requests getting false spends out spends increase more budget , stops after time. simulated call j meter , found this.
as far find node async time status updated 11 many threads have updated spent campaign.
how have semaphore kind of logic node.js variable budget in sync model
update
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 of code can please
q: there semaphore
or equivalent in nodejs
?
a: no.
q: how nodejs
users deal race condition?
a: in theory shouldn't have there no thread
in javascript
.
before going deeper proposed solution think important know how nodejs
works.
for nodejs
driven event based architecture. means in node
process there event queue contains "to-do" events.
when event
gets pop
queue, node
execute all of required code until finished. async
calls made during run spawned other events
, queued in event queue
until response heard , time run them again.
q: can ensure 1 request can perform updates
database @ time?
a: believe there many ways can achieve 1 of easier way out use set_timeout
api.
example:
api.get('/clk/:spent/:id', function(req, res) { var data = { id: id spending: spent } canproceed(data, /*functions 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 released. proceed. next(data.spending, data.id) } } checkbudget(spent, id){ var obj = in memory model[id] obj.is_updating = true; // lock model obj.spent+= spent; obj.spent > obj.budjet // if greater. obj.status = 11 // 11 stopped status update db , rebuild model. obj.is_updating = false; // unlock model }
note: got here pseudo code you'll may have tweak bit.
the idea here have flag in model indicate whether http request
can proceed critical code path. in case checkbudget
function , beyond.
when request comes in checks is_updating
flag see if can proceed. if true
schedules event, fired in second later, "settimeout" becomes event , gets placed node
's event queue later processing
when event gets fired later, checks again. occurs until is_update
flag becomes false
request goes on stuff , is_update
set false again when critical code done.
not efficient way gets job done, can revisit solution when performance becomes problem.
Comments
Post a Comment