question

Christopher Clogg avatar image
Christopher Clogg asked

Cloud script 'staticValue' to improve speed?

Hi, we are running a scheduled task once a day that executes a cloud script on all active players. I noticed a couple occurrences of 'execution time limit exceeded' in our dashboard, I guess because we are hitting that 1s limit for a few random people (about a handful per 10k users). The script involves getting our item catalog which I suspect is the biggest time hog. I was reading https://community.playfab.com/questions/14498/use-of-cached-objects-in-cloudscript.html and wondering if this could help? Like if the first script that runs is able to retrieve and cache the catalog as a static variable in javascript, would then other subsequent runs in that scheduled-task make use of that? Or am I thinking of this wrong?

Also, if this did indeed work, could I make any assumptions about the static variable resetting after the task is done? ie all of the servers spin down.

On a related note, I posted on some other threads about catalog-request filters (or being able to retrieve Stores via cloud script), but perhaps this would be a decent improvement on my end for now.

Thanks!

apisCloudScript
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Andy avatar image
Andy answered

It could absolutely help. It's not quite as simple as the cache lasting for the length of the scheduled task, though. We spin up V8 script instances and load them with your title's cloud script. These instances could live for minutes or days. The number of instances we spin up has to do with the overall concurrency level of your cloud script calls. A cache is scoped to a single instance of the script engine.

However, the nice thing about this design is that your script can just worry about its own cache and invalidate it after a certain period of time at your discretion. It's absolutely a perf improvement to do something like this for your catalog.

4 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Christopher Clogg avatar image Christopher Clogg commented ·

Okay, that is great to hear! So to double check: basically I can assume that if I am running a cloud script 'Scheduled Task' on a large segment, it's likely many of the runs are on the same instance behind the scenes... so a static javascript variable that is set on the first run would then *most likely* apply to many of the subsequent runs.

Regarding your 2nd point, I guess I could also have a static variable that is a date of when the static catalog variable was updated, and then the cloud script could check that to determine needing a refresh?

0 Likes 0 ·
brendan avatar image brendan Christopher Clogg commented ·

To be specific, there's no guarantee that a Cloud Script handler for any one player will re-use a VM that has the script loaded for your title (and so has static values cached). Depending on your concurrent user count and exact usage pattern for Cloud Script, you could have more than a few VMs running your script code.

However, caching values that take time to retrieve is a good technique to optimize the Cloud Script processing time for the majority case, if you have a non-trivial user population. And what I mean by that last part is, if your title doesn't use Cloud Script at all - for any player - for a period of time, you won't have any VMs running with your script code. So in that case, the cached values wouldn't exist.

1 Like 1 ·
Christopher Clogg avatar image Christopher Clogg brendan commented ·

Ah okay. We average a few cloud script calls per minute, but then once every 24 hours we have this scheduled task which runs on tens of thousands of people in a short span. Each individual run has to grab our item catalog, so I figure if I can cache like in that post I linked, it might save many of the tasks from wasting time. I still have to read up on how static variables work in Javascript, seems like it's not as simple as Java/C#/C++... not sure if this is the best way to do it with cloud script... https://stackoverflow.com/questions/1535631/static-variables-in-javascript

0 Likes 0 ·
Show more comments
Christopher Clogg avatar image
Christopher Clogg answered

After Andy's and Brendan's advice, I was able to get it working. I did some test runs with this and logged whether it was fresh or cached data and indeed many runs successfully used the cache, lowering execution time. Here is my code in case it helps anyone else:

function getCachedPlayfabCatalog() {
    var lastCacheDate = new Date(0);
    if (typeof getCachedPlayfabCatalog.cacheDate != 'undefined') {
        lastCacheDate = getCachedPlayfabCatalog.cacheDate;
    }
    var currDate = Date.now();
    var hoursSinceLastCache = (currDate - lastCacheDate) / 36e5;
    if (typeof getCachedPlayfabCatalog.catalogItems == 'undefined' || hoursSinceLastCache >= 1.0) {
        var getCatalogItemsResponse = server.GetCatalogItems({ CatalogVersion: null });
        getCachedPlayfabCatalog.catalogItems = getCatalogItemsResponse.Catalog;
        getCachedPlayfabCatalog.cacheDate = currDate;
    }
    return getCachedPlayfabCatalog.catalogItems;
};

And then in my actual function or handler function, I would call it like so:

var catalogItems = getCachedPlayfabCatalog();
if (catalogItems == null || catalogItems.length <= 0) {
	return "Error: could not load items.";
}
etc...
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.