Suppose I have multiple instances of an app reading a single row with a query like the following
r.db('main').
table('Proxy').
filter(r.row('Country').eq('es').and(r.row('Reserved').eq(false))).
min(r.row('LastRequestTimeMS'))
the 'Reserved' field is a bool
I want to guarantee that the same instance that have read that value do an update to set the 'Reserved' value to true to prevent other instances from reading it
can someone please point me to how I can make this guarantee?
Generally the way you want to do something like this is you want to issue a conditional update instead, and look at the returned changes to get the read. Something like document.update(function(row) { return r.branch(row('Reserved'), r.error('reserved'), {Reserved: true}); }, {returnChanges: true}).
Related
I am working with some coaching using Redis in Nodejs.
here is my code implimentation.
redis.get(key)
if(!key) {
redis.set(key, {"SomeValue": "SomeValue", "SomeAnohterValue":"SomeAnohterValue"}
}
return redis.get(key)
Till here everything works well.
But let's assume a situation where I need to get the value from a function call and set it to Redis and then I keep getting the same value from Redis whenever I want, in this case, I don't need to call the function again and again for getting the value.
But for an instance, the values have been changed or some more values have been added to my actual API call, now I need to call that function again to update the values again inside the Redis corresponding to that same key.
But I don't know how can I do this.
Any help would be appreciated.
Thank you in advanced.
First thing is that your initial code has a bug. You should use the set if not exist functionality that redis provides natively instead of doing check and set calls
What you are describing is called cache invalidation and is one of the hardest parts in software development
You need to do a 'notify' in some way when the value changes so that the fetchers know that it is time to grab the most up to date value.
One simple way would be to have a dirty boolean variable that is set to true when the value is updated and when fetching you check that variable. If dirty then get from redis and set to false else return the vue from prior
I'm in a loop where I add several new keys (about 1 to 3) to an indexeddb row.
The dexie table looks like:
{
event_id: <event_id>
<event data>
groups: {
<group_id> : { group_name: <name>, <group data> }
}
}
I add the keys using Dexie's modify() callback, in a loop:
newGroupNr++
db.event.where('event_id').equals(event_id).modify(x => x.groups[newGroupNr]=objData)
objData is a simple object containing some group attributes.
However, this way when I add two or three groups, only one group is actually written to the database. I've tried wrapping them in a transaction(), but no luck.
I have the feeling that the issue is that the modify()-calls overlap each other, as they run asynchronously. Not sure if this is true, nor how to deal with this scenario.
Dexie modify():
https://dexie.org/docs/Collection/Collection.modify()
Related:
Dexie : How to add to array in nested object
EDIT: I found the problem, and it's not related to Dexie. However, I do not fully understand why this fix works, perhaps something to do with that in javascript everything is passed by reference instead of value? My theory is that the integer newGroupNr value was passed as reference, and in the next iteration of the loop, before Dexie was able to finish, incremented, causing effectively two creations of the same key. This fixed it:
newGroupNr++
let newGroupNrLocal = newGroupNr
db.event.where('event_id').equals(event_id).modify(x => x.groups[newGroupNrLocal]=objData)
There's a bug in Safari that hits Dexie's modify method in dexie versions below 3. If that's the case, upgrade dexie to latest. If it's not that, try debugging and nailing down when the modify callbacks are actually happening. A transaction won't help as all IDB operations go through transactions anyway and the modification you do should by no means overwrite the other.
Is it acceptable to perform multiple increment operations on different fields of the same object on Parse Server ?
e.g., in Cloud Code :
node.increment('totalExpense', cost);
node.increment('totalLabourCost', cost);
node.increment('totalHours', hours);
return node.save(null,{useMasterKey: true});
seems like mongodb supports it, based on this answer, but does Parse ?
Yes. One thing you can't do is both add and remove something from the same array within the same save. You can only do one of those operations. But, incrementing separate keys shouldn't be a problem. Incrementing a single key multiple times might do something weird but I haven't tried it.
FYI you can also use the .increment method on a key for a shell object. I.e., this works:
var node = new Parse.Object.("Node");
node.id = request.params.nodeId;
node.increment("myKey", value);
return node.save(null, {useMasterKey:true});
Even though we didn't fetch the data, we don't need to know the previous value in order to increment it on the database. Note that you don't have the data so can't access any other necessary data here.
With NeDB the first statement will update the data correctly, but the second (using the doc value itself as key(and yes docs[i].ID is '2013000060')
won't work - even the result of the update function tells me that 1 row was changed.
1. oDB.update({ MYID: '2013000060' }, { $set: { "PAGE": 2 }}, ...
2. oDB.update({ MYID: docs[i].ID}, {$set: {"PAGE": 2}}, ...
Some ideas?
Take in account that updates in NeDB work asynchronously.
Anything you want to do after updating an object (and relying on that updated values) should be done inside the callback function you pass to the .update() call.
After fiddling around with NeDB datastore.js it turned out that this is sort of a weird timing problem.
The value is actually updated, but when a .find with a query was issued, the value was not yet persisted.
Anyway did I not go deeper to investigate the fact that using string literals yielded different results.
Could you copy paste the exact code you're using, the expected results and the actual results ? From the look of it it seems like you are using synchronous code where you should use callbacks.
I'm using Redis to store a bunch of "Foos" in a hash:
foo:<id> => {
name = 'whatever',
status = 'incomplete|complete|removed',
user = <user_id>,
...
}
I want to set up an index so I can pull Foos with a particular status for a particular user. Best thing I've come up with is using sets named like so:
foo:user:<user_id>:status:<status> => [ <foo_id>, <foo_id2>, ... ]
But that seems very clunky, and I'd have to make sure to track the old status and remove it from one set when I change the status, to keep data consistent. Is there a more clever structure I can use here?
I think the way you're thinking about storing this stuff is fine. You can always change the foo:user:<user_id>:status:<status> name, if you think it's too long, but the idea makes sense. The one thing I'd add is you should make a short lua function that updates statuses for you by getting the old status from a foo, updating that foo's status to the new status, and then updating the old status' set and the new status' set. Those operations are each O(1), so it won't be expensive (especially since its Lua), and since everything will be managed by one little script, you won't need to worry about doing it all in your code every time.