Android Question Using a FIFO to handle temporary loss of connectivity

pjetson

Member
Licensed User
Longtime User
I'm writing an app that needs to periodically send data to a web host. Because I want to handle the situation when there is temporarily no connectivity, I need to be able to store data that I am currently unable to send, and then try to send it again later. And, of course, sending it later might fail too.

So, I thought that a FIFO buffer might be the right kind of "device" to use. And it looks like the B4A LIST function does almost everything needed, except for an easy way to remove items from the buffer, oldest first. I guess I can't expect all of the work to be done for me!

Anyway, what I propose is that I store my http POST transactions into the buffer, then have a sub that tries to send the buffer one item at a time. If this fails, I'll set a timer to timer to retry every 15 minutes, until the buffer is empty.

Does anyone forsee any problems with this scheme, or have any alternative ideas?
 

pjetson

Member
Licensed User
Longtime User
Don't you need to persist the data somehow? Is it ok for the data to be lost when the user closes your app?
You're right, Erel, of course. Clearly, I hadn't thought that part through enough. I will need to modify my plan so that the unsent data is saved somewhere safe in case the app is closed.
 
Last edited:
Upvote 0

pjetson

Member
Licensed User
Longtime User
What I've done so far seems easier than that, Erel. The data that I need to send is simple JSON datasets, and I am storing them in memory as a List, and using File.Writelist and File.Readlist to save the list as necessary.

When the app starts up, it checks to see if the file exists, and if it does, it loads the JSON items from it into a List. Each time I am able to remove some or all of the items in the List because I have connectivity again, I write the updated file back again. And each time I have to add an item to the List due to lack of connectivity, I also update the file again.

I have all this working in a short test program, and I'm currently in the process of moving the test code into my app.

I have still to write the 15 minute timer code that attempts to send any buffered data, but that shouldn't be a problem. I was thinking about using a single sub called from the main program event and the timer event, but it might be easier to use two separate subs unless B4A has some type of mutex facility. Otherwise, if the timer event happens at the same time as the main program event, bad things might happen.
 
Upvote 0

pjetson

Member
Licensed User
Longtime User
Why not just a simple Map?
According to the docs, a map is "a collection that holds pairs of keys and values", while a list is similar to a dynamic array where you can add and remove items from a list and it will change size accordingly.

In my application, I basically wanted a FIFO queue where I could append items to the list as required, and remove them, oldest first, when possible. A list just seemed a more natural fit (ie I'd have needed to do a lot more work if I used any other structure!).

Each data item is a simple (ie no arrays) JSON dataset, which by using objJSon.ToString effectively becomes a simple string (ie it no longer matters what's in the string).

Setting up the FIFO buffer is easy:
B4X:
Dim Buffer As List
Buffer.Initialize

Adding an item to the FIFO buffer is easy:
B4X:
Buffer.Add(objJSon.ToString)

Removing an item from the FIFO buffer is also easy:
B4X:
item = Buffer.Get(0)
Buffer.RemoveAt(0)

Here's how I save the buffer to persistent storage:
B4X:
File.WriteList(File.DirInternal, "buffer.txt", Buffer)

And here's how I load it back from persistent storage:
B4X:
Buffer = File.ReadList(File.DirInternal, "buffer.txt")

Being a B4A newbie, it did take me a while to work all that out, but it's hard to imagine how the result could be any simpler.
 
Upvote 0
Top