Reconnect logic with connectivity notifications - sockets

Say I have an application that wants a persistent connection to a server. How do I implement connection/re-connection logic so that I'm not wasting resources (power/bandwidth) and I have fast reconnect time when connectivity appears/improves? If I only use connectivity notifications, I can get stuck on problems not related to the local network.
Bonus if you could show me the C# version.
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

This is a very "huge" question. I can say that we use an O/R Mapper and each "query" to the database needs an object called PersistenceBroker. This class is in charge of all the DB Stuff related to connecting, authenticating etc.
We've written a PersistenceBrokerFactory.GetCurrentBroker() which returns the "working" broker. If the DB suddenly fails (for whatever reason), the CONN object will "timeout()" after 30secs (or whatever you define). If that happens, we show the user that he/she is offline and display a reconnect button.
On the other hand, to provide a visual indication that the user has connectivity, we have a thread running in the background, that checks for Internet connectivity every 15 seconds. We do 1 ping to google.com. ;) If that fails, we assume Internet is somehow broken, and we update a status bar.
I could show you all that code for the network health monitor if you wanted. I took some bits from google and other I made myself :)

Related

Identify which service listens for notifications but doesn't consume them

I have a huge database where, in some places, we use Postgres notifications. We noticed that the queue size is increasing. The way we check is executing this simple command: select pg_notification_queue_usage();.
When it reaches 100% then all messages are gone. The problem I have is that I don't know who listens to notifications and what channels we have there. I identified only two services that listen for those notifications but it seems that's not the case.
My task is to find other places where we use notifications (consume or produce) to find the root cause. How can I do it?
The only thing I found about it is the query select pg_notification_queue_usage(); but it seems that Postgres doesn't provide other useful functions related to this feature.
I did some experiments regarding it. I launched a local Postgres instance and started publishing notifications there. Everything worked as expected. When I did it once again but without actual consuming notifications, the queue size started to grow. That's what I expected, tho.
Then, I restarted the process and the queue size dropped to 0. That's exactly what the docs say about it.
A session's listen registrations are automatically cleared when the session ends.
On the production, we did exactly the same - we restarted known services but the notification queue didn't drop to 0 as we expected.
It means, there's something else listening to one of the channels but it doesn't consume it or does it too slow.
Is there any way of identifying such listeners?

Is there a way to disable long calls to Firestore/Listen?

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

CBPeripheral being disconnected with UnknownError Code=0 after calling writeValue

I'm developing an app that uses Bluetooth to communicate with Smart Devices.
It needs to authorise iPhone with such scheme:
Scanning devices with some filters of services UUIDs
Connecting to a device, discovering services, discovering characteristics
Calling read operation to retrieve public keys
Exchange received public keys (using ECDH)
Generate token
Write encrypted token (using AES) to device using writeValue
That's all, after that I have stable connection and able to interact with my Smart Device (writing values to protected properties).
The question is that when I restart my app and do all of the steps above, except Step_5 (because I have my token generated and validated previous time), on Step_6 delegate method didWriteValueFor: doesn't even get called, instead of this delegate method didDisconnectPeripheral being called with Error Domain=CBErrorDomain Code=0 "Unknown error." UserInfo={NSLocalizedDescription=Unknown error.} and I can't write values to protected characteristics.
I can't get what I'm doing wrong. Any help would be nice.
UPD[0]: Sometimes I can get a callback for didWriteValueFor: on Step_6 but IMMEDIATELY (like less than a 0.5 sec) iPhone is being disconnected with an error from above.
UPD[1]: Also I was trying to cancelPeripheralConnection() before closing my app because Smart Device does not handle multiple connections in hardware reasons, but no luck here.
UPD[2]: Well, after three days of searching for information, I realized that I was digging in the wrong direction at all. The problem was that I interrupted the application with the “Stop” button in Xcode, and didn’t close it manually via iPhone, therefore, willTerminate was not called, and even if it was called, it had a very limited amount of time to execute all the processes that were supposed to be executed, as a result, the connection didn’t interrupt (the cancelPeripheralConnection method was not called), and the next time I started the App, I tried to establish a connection with a device that already has a connection to my App.
At least it started connecting often, but I'm still getting this error sometimes. The main question is: how properly disconnect from the device? For now I’m unsubscribing from all the properties that have isNotify: true (setting to false) and call cancelPeripheralConnection. Do I need to wait the “unsubscribe” process before disconnecting?
UPD[3]: It doesn't matter if I wait for unsubscribe finished or not. At least it have no effect.
Well, I found the reason why disconnects are appears:
Since Smart Device has several characteristics of public keys that need to be read, encrypted and then sent back, the order keys I read and write was important. Since writeValue and readValue are asynchronous, my order went astray. As soon as I began to keep order, everything worked like a clock.

Can I use async controllers in the following scenario?

I have an application in Asp.net MVC where at some point I would like to display a modal dialog to the user that would display process execution progress indicator.
The process behind the scenes does a lot of database data processing (based on existing data it generates lots of resulting records that get written back to database as well). Process may take anything from a brief moment to a very long time (depending on existing data).
Application will initiate this process asynchronously (via Ajax request) and display progress in the same manner.
The problem
I've read a bit about Async controllers where one can asynchronously start a process and will informed about the end of it but there's no progress indication and I'm not really sure how browser timeouts are handled. As far as the client goes an async request is the same as synchronous one. Client will therefore wait for response (as I understand it). the main difference being that server will execute something in async manner so it won't block other incoming requests. What I should actually do is:
make a request that would start the process and respond to the client taht process has started.
client would them periodically poll the server for process progress status getting immediate response back with percentage value (probably as JSON)
when progress would be 100% it would mean that it ended so client would know to make a request for results.
I'm not convinced that async controllers work this way...
The thing is that I'm not really sure I understand async controllers hence am not sure which approach should I use approach this problem as just described? I see two possibilities myself:
Asp.net MVC Async controllers if they can work this way
Windows Service app that processes data on request and reports its progress - this service would be started by writing a particular record to DB using a normal controller action; that would start it and then service would be writing its progress status to DB so my Asp.net MVC app would be able to read it on client process polling requests.
I haven't used Asynch controllers myself in a project. However here's a link to someone who has.
asynchronous-processing-in-asp-net-mvc-with-ajax-progress-bar
I have personally used Number 2 in a large production project.
Number 2 was a Service App running on a separate server using OpenSSH to communicate between the two servers. We'd poll for progress periodically to update the progress bar to the clients UI via AJAX.
Additionally by separating your web server from your long running process you are separating your concerns. You web server is not interested in writing files to disk, handling IO, etc and so shouldn't be burdended with such.
If your long running process has to be killed or fails then this wont affect your web server handling requests, and processing transactions.
Another suggestion would be for an extremely long running process is not to burden the client with waiting, give them an option to come back later to see the progress. I.e. send them an e-mail when its done.
Or actually show them something interesting, in our case we had a signed Java Applet show exactly what their process is doing at that exact moment.

No Internet Connection

I am a little confused on how to go about and do this....
On each page of my app i connect to PHP file to drag in data from my server. I have about 10 pages. Now if there is no connection to the internet then of course now data can be received.
Often the app crashes and we are putting this down to not having the data due to a change in connection or wifi whatever.
Now i have setup the reachability thing and that works, but i dont know how to link this in with the PHP calls. Should i check the reachability and if no connection then dont run the call. If so, what about all the variables, they will still be null and cause an error then?
I dont really know what is the best solution.
Hope you can help
Alex
Are the php calls just to receive data from a database without using a built in DB framework such as SQLite? If so, I went the same route to avoid the headache at first, but running SQLite in your app is a better solution overall, and reduces multiple dependencies (such as internet connection).
Now if the php calls that give you data back are receiving this information from yet another source and then feeding it into its own DB.....
Should i check the reachability and if no connection then dont run the call
Yes you should. This is done in multiple apps already. What variables would be null in this case? Pop the code that makes the call in an "if" block below this check, and only run it if true. Error handling other variables that might be null because the php call isn't setting them is up to you. You can do this is multiple ways.
You should certainly cache the data so the App doesn't HAVE to connect to the internet to display something, other than that I would make sure to use asynchronous requests and the timeout feature of NSURLRequest to control your attempts to request data in the background. If you don't get the data, just keep using what you have cached.