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
Related
I am trying to develop a webapp using Google Apps Script to be embedded into a Google Site which simply displays the contents of a Google Sheet and filters it using some simple parameters. For the time being, at least. I may add more features later.
I got a functional app, but found that filtering could often take a while as the client sometimes had to wait up to 5 seconds for a response from the server. I decided that this was most likely due to the fact that I was loading the spreadsheet by ID using the SpreadsheetApp class every time it was called.
I decided to cache the spreadsheet values in my doGet function using the CacheService and retrieve the data from the cache each time instead.
However, for some reason this has meant that what was a 2-dimensional array is now treated as a 1-dimensional array. And, so, when displaying the data in an HTML table, I end up with a single column, with each cell being occupied by a single character.
This is how I have implemented the caching; as far as I can tell from the API reference I am not doing anything wrong:
function doGet() {
CacheService.getScriptCache().put('data', SpreadsheetApp
.openById('####')
.getActiveSheet()
.getDataRange()
.getValues());
return HtmlService
.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getData() {
return CacheService.getScriptCache().get('data');
}
This is my first time developing a proper application using GAS (I have used it in Sheets before). Is there something very obvious I am missing? I didn't see any type restrictions on the CacheService reference page...
CacheService stores Strings, so objects such as your two-dimensional array will be coerced to Strings, which may not meet your needs.
Use the JSON utility to take control of the results.
myCache.put( 'tag', JSON.stringify( myObj ) );
...
var cachedObj = JSON.parse( myCache.get( 'tag' ) );
Cache expires. The put method, without an expirationInSeconds parameter expires in 10 minutes. If you need your data to stay alive for more than 10 minutes, you need to specify an expirationInSeconds, and the maximum is 6 hours. So, if you specifically do NOT need the data to expire, Cache might not be the best use.
You can use Cache for something like controlling how long a user can be logged in.
You could also try using a global variable, which some people would tell you to never use. To declare a global variable, define the variable outside of any function.
When I create a function like this:
v8::Function::New(<Isolate>, <C_Function>, <Data_Value>);
The Data_Value that I supply is useful for many things and I can access that when the function is called, with something like FunctionCallbackInfo->GetData().
But I have found no way to get back this data in a different scenario. Let's say I store that Function in a Persistent object, and then I would like to read which data is currently bound to it. Any ideas?
I don't think it's exposed via the API.
But there's an alternative:
manually construct a v8::FunctionTemplate
set its ->InstanceTemplate()->SetInternalFieldCount(num_fields)
get the v8::Function from the template with template->GetFunction(context),
now you should have function->InternalFieldCount() == num_fields
you can use function->SetInternalField(index, value) and function->GetInternalField(index) to store any data you want.
For complete examples, search for "SetInternalFieldCount" in V8's test-api.cc.
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.
I'm trying to check the current and previous value of an attribute in the beforeSave(). So i tried to use request.object.previous("attribute_name") but it is still returning the current changed value. Although the .ditry() is returning TRUE which means that the value is changed. Any idea what is wrong here ? I appreciate your feedback.
I think the .previous() isn't actually part of the Parse.com sdk, but simply inherited from backbone.
In a beforeSave handler, I have something like:
if(object.dirty("attr")) {
console.log("After: " + object.get("attr") + ", Before: " + object.previous("attr")); }
The value returned by 'previous' is always the same. Is this functionality actually
implemented? I've seen a few threads elsewhere that imply it's not -
if so, can you remove it from the API docs until it's done?
If it doesn't work, is the correct workaround to query the previous
object? Or does 'changedAttributes' work?
Oh, I now see that 'previous' is some cruft from Backbone.
source1
previous is a method inherited from Backbone.Model. It won't return the previous value of a field in Cloud Code.
source2
Might not be the answer you're looking for, so as a way to workaround the lack of the .previous implementation this this out:
Don't know if this is helpful or if it would be considered too costly
of a workaround, but you could add a column to the object that is
being updated that stores the previous value of the original column.
This would allow you to access the previous value in the AfterSave
function.
I am trying to develop a webapp using Google Apps Script to be embedded into a Google Site which simply displays the contents of a Google Sheet and filters it using some simple parameters. For the time being, at least. I may add more features later.
I got a functional app, but found that filtering could often take a while as the client sometimes had to wait up to 5 seconds for a response from the server. I decided that this was most likely due to the fact that I was loading the spreadsheet by ID using the SpreadsheetApp class every time it was called.
I decided to cache the spreadsheet values in my doGet function using the CacheService and retrieve the data from the cache each time instead.
However, for some reason this has meant that what was a 2-dimensional array is now treated as a 1-dimensional array. And, so, when displaying the data in an HTML table, I end up with a single column, with each cell being occupied by a single character.
This is how I have implemented the caching; as far as I can tell from the API reference I am not doing anything wrong:
function doGet() {
CacheService.getScriptCache().put('data', SpreadsheetApp
.openById('####')
.getActiveSheet()
.getDataRange()
.getValues());
return HtmlService
.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getData() {
return CacheService.getScriptCache().get('data');
}
This is my first time developing a proper application using GAS (I have used it in Sheets before). Is there something very obvious I am missing? I didn't see any type restrictions on the CacheService reference page...
CacheService stores Strings, so objects such as your two-dimensional array will be coerced to Strings, which may not meet your needs.
Use the JSON utility to take control of the results.
myCache.put( 'tag', JSON.stringify( myObj ) );
...
var cachedObj = JSON.parse( myCache.get( 'tag' ) );
Cache expires. The put method, without an expirationInSeconds parameter expires in 10 minutes. If you need your data to stay alive for more than 10 minutes, you need to specify an expirationInSeconds, and the maximum is 6 hours. So, if you specifically do NOT need the data to expire, Cache might not be the best use.
You can use Cache for something like controlling how long a user can be logged in.
You could also try using a global variable, which some people would tell you to never use. To declare a global variable, define the variable outside of any function.