Discord Cache, how long does it last? - discord.js

guild.members.fetch()
Returns a cached response. Is there a way to determine how long it takes for the cache to refresh?
Is there a fixed amount of time that passes between regular refreshes?
I am aware that the call returns a promise and must be either awaited or handled with .then(). I was actually wondering about the returned result of the call; how often discord clears it's own cache.
Thanks.

That function returns a promise, which resolves when all the members are fetched successfully and the cache is set. Simply await this promise to get updated cache.
// note this returns a Collection of the members who were fetched and cached
await guild.members.fetch()
console.log(guild.members.cache.size) // should log the real amount of members in the server

Related

Calling memcache.set_multi_async doesn't save values

I'm currently using the Google memcache API in my Google Appsengine application to store a large amount of data in cache, however this needs to happen asynchronously as I need to return a result before it is done.
I already found an answer here stating how it is done, however I still can't get my code to work.
I tried using this, however it simply causes memcache to be store the values synchronously:
client = memcache.Client()
rpc = client.set_multi_async(values)
rpc.get_result()
return values[id]
I also tried this, but it causes memcache to never save the values:
client = memcache.Client()
client.set_multi_async(values, rpc=memcache.create_rpc())
return values[id]
Is there any way to store the values asynchronously and return a value at the same time? Thanks
rpc.get_result() causes the rpc object to wait until the result is available before returning, thus making your code synchronous. In order to make your code asynchronous, you would need to return the rpc object(s) and then use the Future class to wait for and handle results when they are ready.

$cacheFactory + API calls: Updating Cache

My API calls are automatically being cached in the default cache provided by $cacheFactory ({cache: true}). If I add another record to the DB I want to be able to add the relevant information (which is returned from the post API call to add the record) to the cached information I have rather than deleting the cache and having it re-request all the data.
var $httpDefaultCache = $cacheFactory.get('$http');
var data = $httpDefaultCache.get(key)
The key is the path of my API request. Data is just an array. Element 1 is my stored data which is a hash containing arrays. I planned to simply add to it my new record. However when I retrieve it ($httpDefaultCache.get(key)[1]), I don't get a hash. I get a string. I could just take said string and transform it into a hash or simply add to the string, but I think I'm missing a key component of retrieving data from the cache. Thoughts?
An answer of how I went forward in case anyone runs into a similar problem.
Let's say you used $http to make a get request to an API with cache set to true.
Set the return value of this request within your controller to whatever; we'll use $scope.politicians.
Since we used the default cache, we can retrieve it by $cacheFactory.get('$http')(cachedUrl).
Remove the cache by doing $cacheFactory.get('$http').remove(urlOfGetRequest)
Make any changes I want to the $scope value that was initially set to the return value from the API call and then reset the cache to that scope when finished.
$scope.politicians[new-key] = new-value;
Set the cache again, but use your scope as the value.
$cacheFactory.get('$http').put(urlOfGetRequest, $scope.politicians);
Using the non-default cache makes this process rather easier.
I swear there must be a more direct way of doing this. But I could not find it.

What is the difference between .all() and .one() in Restangular?

What is the difference between these two? Both seems to make a GET to /users and retrieve them.
Restangular.one('users').getList().then(function(users) {
// do something with users
});
Restangular.all('users').getList().then(function(users) {
// do something with users
});
I understand that you can do one('users', 123) and it will retrieve /users/123 but without the second argument it seems to be the same thing. Why not just have one method in that case?
The one() function has a second argument that accepts an id e.g. .one('users', 1).
one('users', 1).get() translates to /users/1
all('users').getList() translates to /users
Unlike all(), one() is not generally used with .getList() without argument. However, if you were to call .one('users', 1).getList('emails') or .one('users', 1).all('emails').getList(), then you would make a GET request to /users/1/emails.
My guess is that they are there for expressing an intention of what you are going to do. I would understand those as a way to build the url, expressing if you are accessing to the whole resource or to a specific one.
In the end, they are gonna build and do a GET request but because you do a GET and retrieve some data it does not mean that it should be used in that way.
Example extracted from https://github.com/mgonto/restangular/issues/450
getList can be called both ways. If it's called in an element one,
then it needs a subelement to get to a Collection. Otherwise, it
fetches the collection. So the following is the same:
Restangular.one('places', 123).getList('venues') // GET /places/123/venues
Restangular.one('places', 123).all('venues').getList() // GET /places/123/venues
As you can see, it is more expressive to call one('places', 123).all('venues') to understand that you just want the venues located in the area/place 123.
Maybe the following url will help you:
https://github.com/mgonto/restangular/issues/450
I've recently discovered a difference between these methods. Yes, both of them make the same get requests, but the results you get might surprise you (as they surprised me).
Let's assume we have an API method /users which returns not strictly an array, but something like this:
{
"result": [{...}]
}
So an array is returned as a value of some prop of the response object. In this case get() and getList() work differently. This code works well:
Restangular.get('users').then(function (response) {...});
Your response handler gets invoked after response has been received. But this code doesn't seem to work:
Restangular.all('users').getList().then(function (response) {...});
Response handler is not invoked, despite that request completed with status code 200 and non-empty response. Browser console doesn't show any errors and network monitor shows successful request.
I've tested this with Restangular 1.5.2 so probably this is already fixed in newer versions.

What if I never call get on the future from an Async Data Store operation?

If I call an async data store operation such as the one shown below but then end the request without calling get on the future, what will happen?
Will my operation still execute?
Will me response be sent before the operation has completed execution?
AsyncDatastoreService datastore = DatastoreServiceFactory.getAsyncDatastoreService();
Entity entity = new Employee("Employee", "Alfred");
// ... populate entity properties
// Make a sync call via the async interface
datastore.put(key)
//Return response
The rpc will be sent immediately; when your app is ready to send a response to the client, it will block until the rpc is done.
I've done this in python by accident and the result was nothing was written to the datastore.
Your operation may still execute but it seems that'll happen only if the response handler is still active when it decides to execute. If not, nothing seems to happen at all.
Yes, the response will be sent before the operation has completed execution - this is the main feature of a future, it's non-blocking.

How do I cancel an asynchronous operation in Silverlight/WCF?

I am calling an asynchronous service from my Silverlight app and I want to be able to cancel that call after it is made. There is an option for e.Cancelled once the service has finished (i.e. If e.Cancelled Then), but how to you set that cancelled to true after you have called it? How do you cancel that asynchronous call?
Let me clarify a bit... what I am trying to do is call the SAME method twice, one right after the other, and get the results of the last call into my collection. If I call an asynchronous method twice there is no guarantee that the second call will return first, so I may end up with the results of the first call coming in last and having the wrong results in my collection. So what I would like to do is cancel the first call when I make the second so I don't get results back from the first call. Seeing as how there is a Cancelled flag in the completed event args I figure you should be able to do this. But how?
It's async... the transfer is passed off to a remote server and it does not return until the server is done with it.
Basically the server will keep going, but you don't have to wait for the response. Disconnect your service completed event handler and pretend it was never called. That will give the effect of cancelling the operation.
If you really need to cancel something in progress on the server you would need to make another call to the server to cancel the first call. Assuming the first call is a very slow one, this might be possible.
Update (as question changed)
In the case you specify, it will be up to the server to cancel a operation in progress if a second one comes through, not up to the client. e.Cancelled is set server-side.
However... :)
You have exposed a client usability issue. Shouldn't you also delay sending any service request until an idle delay has passed. That way rapid selections will not result in multiple service calls.
Also... :>
You may also want to send a sequence number to your service calls and return that as part of the result. Then you will know if it is the latest request or not.
It sounds like what you really want to do is ignore the responses of all but the most recent call.
Set a unique ID (could be request #, a Guid, timestamp, or whatever) with the request, and make sure the service sends that same value back. Keep around the ID of the most recent request and ignore response that don't match that ID.
This will be safer than cancelling the first request, since if the service has already started sending the response before the cancel request happens, you still get your error condition.

Resources