0

I'm developing an application that handles sales for multiple clients, when the client sells a particular item, that information should be send to the admin. The count of each item sold and the item names.

I've done that by setting a simple server online and sending POST requests to that server with the appropriate data, I send the item name and the change in sale since last update. The problem I'm facing is if the request fails for whatever reason (server is down, or internet is unavailable, etc.) What is the best approach to such a problem?

What I did is that I store the change locally on the client's machine. In my current implementation, I set a value in the registry with the item's name to the change. I try to send that change to the server and if that request is successfull, I remove that value from the registry. This works, but only informs the server when the client sells another of the same item.

For example, the client sold three of Item A and two of Item B, the request was sent correctly so the server is up to date. Later, there was no internet access and the client sold two extra of Item B. Since the request failed, the client is left with "Item B: 2" in his registry. When the internet comes back, the server will not be informed of those two sales unless if the client sells another of Item B. This is extremely undesirable, but I have no idea how to fix it.

To put it clearly: I want to log sales to the server, and if the internet is not accessible, I want to store the logging offline until the internet is back again, at which point the stored logs should be sent. How can I do that?

3
  • 2
    The registry is not the best place to store this information. But you've got the right idea; save the information locally and transmit it when the internet connection becomes available again. Commented Aug 27, 2018 at 20:47
  • Why is the registry not recommended? What should I do instead? Commented Aug 27, 2018 at 21:05
  • Generally speaking, the registry is intended to store small amounts of operating system and application installation and configuration information; it's not designed to accommodate an application's data. Use a local database, a JSON file, or something similar. Commented Aug 27, 2018 at 21:08

2 Answers 2

0

A queue

This is effectively what you already tried to implement, and it is the correct solution. The basic outset is:

  • Try to send the update.
    • If it succeeds, end of work.
    • If it fails, store the update locally, so you can try again later.

No argument there, it is exactly how you should handle this.


A trigger

A trigger is an action that causes a job to be performed. There are many possible triggers:

  • Button - fires whenever it is clicked
  • Timer - fires at the times it is scheduled
  • Conditional - fires if certain criteria are met
    • It's very important to realize here that this is a two-step trigger. The conditional trigger itself is able to launch the job (or not), but you still need a second trigger which is able to lauch checking the conditions of the trigger.

This works, but only informs the server when the client sells another of the same item.

What you have here is a two-step conditional trigger.

  1. When the user sells item A, check if there are other updates for item A.
  2. When there are other updates for item A in the queue, send them.

There's nothing wrong with the second trigger. But as you can see, the problem is in the first trigger. You'll never send an update unless that trigger is fired.

The simplest (but not necessarily best) solution is a button.

  • Whenever a page/window is loaded, check if there are any updates in the local queue (no matter for which item).
  • If there are queued updates, show the "Sync" button.
  • When the "Sync" button is clicked by the user, the updates are sent to the server (if it fails again, the updates stay on the queue and the cycle repeats).

A seemingly better solution is a timed trigger. However, tracking the timer is an "always on" type of algorithm. Depending on whether you're making a web application or a local one, things can be very different here. Just to give you a sampling of possibilities:

  • A WinForms/WPF application can run a timer in the background for as long as the application itself is open. This can arguably also apply to SPA web applications.
  • Alternatively, you could run a separate background application which remains open when the Winforms/WPF app is closed. However, it's morally questionable to do this without the user's express consent.
  • A web application can't reliably run a timer due to repeated page loads. However, it is possible to simply perform a check every time a page is loaded. This very much depends on how often you expect the user to switch pages.
  • You could also run a timer during the lifetime of a single web page, but it's only meaningful if you don't expect the user to switch pages all that often. Also, keep in mind that if the user has multiple pages open, there will be multiple timers, concurrency may be an issue here.
  • If you're running the application on a server that you have control over, you could also have a separate Windows service which is responsible for sending the updates (and queueing them in case of errors), and have your application always send it to the service instead of to the internet.

There are many solutions here. I can't choose the right one for you, that depends on many factors like code complexity, robustness, assurance that updates get sent in a timely fashion, ...

4
  • The timer seems like a very solid idea, except, won't that cause collisions with the normal trigger sending the data? I mean it's rare but possible. I don't want to cause the program to halt while it's trying to send the queued data. Do you know a way to solve this problem? Commented Aug 28, 2018 at 22:56
  • @Megadardery The timer seems like a very solid idea, except, won't that cause collisions with the normal trigger sending the data? The idea is that the job (triggered by either trigger) checks if there is data to send and then sends it. If the job is fired a second time, it finds nothing on the queue and then doesn't send anything. I don't want to cause the program to halt while it's trying to send the queued data. Then you have to send the updates asynchronously (note that a timer and its triggered job would usually already run asynchronously to your UI anyway)
    – Flater
    Commented Aug 29, 2018 at 7:22
  • With the queue option I would let all updates flow though the queue. Process 1 fills the queue, process 2 sends data from the queue to the backend. When network fails or other errors occur items remain in the queue for the next try.
    – Kwebble
    Commented Aug 29, 2018 at 22:02
  • @Kwebble indeed. Instead of only updating A when another A is sold, why not "sell item, send notice, if notice success then check que and send any pending notices, else add notice to que".
    – ivanivan
    Commented Oct 13, 2018 at 17:21
0

I am unsure by the question that it is a desktop app or web app but if it is a desktop app the lightweight database like sqlite, or some caching service can help. or you can derive your own method (json,csv) etc. make sure of security and obfuscation.

Similar goes for web app you can use localstorage or something like that if your data is not too large.

3
  • From the title, it's pretty sure that it is a desktop app. How will web app function in the case of no internet connection?
    – Dishant
    Commented Aug 29, 2018 at 0:31
  • @Dishant I meant to say web app install in local environment. Commented Aug 29, 2018 at 2:50
  • @Dishant: I don't see how the title implies it's a desktop app. The same question would apply to a web app which sends data asynchronously. If the connection suddenly drops, the user wouldn't want to risk losing their data.
    – Flater
    Commented Aug 29, 2018 at 7:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.