Is there a way to disable long calls to Firestore/Listen? - google-cloud-firestore

A long 1 min call to Firestore/Listen is preventing our prerender soln from working properly. The provider waits for all network calls to complete, which means the prerender takes a long time.
We don't use any of the realtime features, so there is no value in listening after requests complete afaict.

First, no it's not possible to directly disable it using some Firestore config option for example.
What you can do is bypass it by using transactions in Firestore. Any operation run in a transaction will use its own connection which will be torn down after. See here for details.
It might also work to shut down Firestore after some timeout in this case. I haven't tried it yet. In theory though for this particular problem I can check the userAgent and shut down fire

Related

How to handle async operation that we would like to cancel

I have an async operation that should run only if a user is connected, and should stop as soon as the user disconnect. For better understanding, I call the function in the example fetchUserDataAndCacheIt even though there is distinct services in charge of fetching and caching.
Future fetchUserDataAndCacheIt() async {
....
}
The problem is, if the user disconnect during fetchUserDataAndCacheIt is running, the cached data will not be valid, as it will be data of a user not connected anymore. Worse, if fetchUserDataAndCacheIt takes a really long time to run (20 seconds), the user have the time to disconnect, an other user can connect on the same machine, then have access to the previous user data trough cache, since fetchUserDataAndCacheIt will end running after the second user connect.
From what I can tell, you cannot cancel a future in dart.
https://github.com/dart-lang/sdk/issues/42855
You could use a completer but it would not solve the problem mentioned above.
For now, what I found is to check whether the user is connected before caching inside the fetchUserDataAndCacheIt function, but I feel like doing that kind of check each time I want to cache any kind of data is going to make the code unmaintainable in the long run.
I hacknowledge this this can only occur in specific cases where the Future take a long time to run, but I cannot just hope the connection of my users to be fast enough for it to never happen.

Is there a standard / built-in way to handle race conditions with CKFetchRecordZoneChangesOperation?

I'm building my first CloudKit application, and am using CKFetchRecordZoneChangesOperation on startup to get any new records changed while the current device was offline.
I am also calling CKFetchRecordZoneChangesOperation when I receive a subscription notification of changes.
It is possible the subscription notification could come in before the startup call finishes. I am currently using a lock to prevent the 2nd call from starting until the recordZoneFetchCompletionBlock handler is called, signalling that the first one is done. This works, but it also smells a bit hacky.

Is there a way to rely on Postgres Notify/Listen mechanism?

I have implemented a Notify/Listen mechanism, so when a special request is sent to the web server, using notify I can notify the workers (in Python) that there's a pending request waiting to be processed.
The implementation works fine, but the problem is that if the workers server is restarting, the notification gets lost, since at that particular time there's no listener.
I can implement a service like MQRabbit or similar, but my needs are so simple that implement such a monster is too much.
Is there any way, a configuration variable perhaps, that can give some persistence to the notification mechanism?
Thanks in advance
I don't think there is a way to persist notification channels, but you can simply store the pending requests to a table, and have the worker check for any missed work on startup.
Either a timestamp or a pending/completed flag would work, depending on what kind of work it's doing.
For consistency, you can have the NOTIFY fire from an INSERT trigger on the queue table, and have the worker always check for any remaining work (not just a specific request) when notified.

Backbone sync request sequence

I've got a Backbone web application that talks to a RESTful PHP server. For PUT and POST it matters in which order the requests arrive at the server and for GET it matters in which order the responses arrive at the client.
The web application does not need to be used concurrently by multiple users, but what might happen is that the user changes its name twice really fast. Then the order in which the server processes PUT /name/Ann and PUT /name/Bea determines whether the name is set to Ann or Bea.
Backbone.Safesync and Backbone.Sync.AjaxQueue are two libraries that try to solve this problem. Doesn't Safesync only solve the problem with GET? Sync.AjaxQueue is outdated, but might serve as inspiration to implement a custom queued sync function. Making sync synchronous would solve the problem. If a request is only sent after the previous response is received, then only one request is processed at a time.
Any advice on how to proceed?
BTW: I don't think using PATCH requests would solve anything, because in my example the same attribute is changed twice.
There's a few ways to solve this, here's two:
add a timestamp to all requests, store it in the DB as "modified" and let the server check whether the timestamp of the new request is later than the one in the DB in order to be valid
use Promises to delay the second request from being made before the first one is responded on, there's a promise/deferred mechanism built into jquery, but you can also use a 3rd party one, for instance Q or when
If you can afford the delay, an easy approach is to set the async option to false when you call whatever method you're calling that results in the Backbone.sync. For example, in the appropriate model(s) simply override the default sync method to include the additional option.

GWT: Is Timer the only way to keep my app up-to-date with the server?

I just got asked to reduce the traffic made by my GWT app. There is one method that checks for status.
This method is an asynchronous call wrapped in a Timer. I know web apps are stateless and all that, but I do wonder if there is some other way to do this, or if everyone has a Timer wrapped around a call when they need this kind of behaviour.
You can check out gwteventservice. It claims to have a way to push server events and notify the client.
I have a feeling they might be implemented as long running (hanging) client to server RPC calls which time out after an interval (say 20sec), and then are re-made. The server returns the callback if an event happens in the meanwhile.
I haven't used it personally but know of people using it to push events to the client. Have a look at the docs . If my assumption is correct, the idea is to send an RPC call to the server which does not return (hangs). If an event happens on the server, the server responds and that RPC call returns with the event. If there is no event, the call will time out in 20 seconds. Then a new call is made to the server which hangs in the same way until there is an event.
What this achieves is that it reduces the number of calls to the server to either one for each event (if there is one), or a call once every 20 seconds (if there isn't one). It looks like the 20 sec interval can be configured.
I imagine that if there is no event the amount of data sent back will be minimal - it might be possible to cancel the callback entirely, or have it fail without data transfer, but I don't really know.
Here is another resource on ServerPush - which is likely what's implemented by gwteventservice.
Running on Google app engine you could use they Channel technology
http://code.google.com/intl/en-US/appengine/docs/java/channel/overview.html
If you need the client to get the status from the server, then you pretty much have to make a call to the server to get it's status.
You could look at reducing the size of some of your messages
You could wind back the timer so the status call goes out less often
You could "optimise" so that the timer gets reset when some other client/server IO happens (i.e. if the server replies you know it is ok, so you don't need to send the next status request).