I'm looking to update a list of orders (and statuses) real-time on a webpage. The orders in the (MySQL) database are updated asynchronously through other processes (PHP).
I'm familiar with the mechanics of pushing data to pages (polling, event-source). This is not about that.
What I'm struggling with is figuring out exactly what data to push for each user without
- needlessly updating list entities that don't need to be
- not missing an update.
My table does have a DateTime column last_update_date
that I update when there are any changes to the order. I know MySQL doesn't really have any event triggers that can trigger other code.
Ideas so far:
- In my JS I could track the time of the last request and on every subsequent request, ask for data since that time. This doesn't work because JS time will most likely not match server MySQL time.
- The same could probably done storing the server time in the user session. I feel like this would probably work most of the time, but depending on the timing of the DB update and the requests, changes could be missed since the DB only stores a DateTime with a precision of 1 second.
I'm sure there's a more atomic way to do this, I am just drawing a blank though. What are suitable design patterns for this?
The solution O.Jones provided would work for making tracking updates atomic, though where it fails is if the following scenario occurs all within one second:
In this scenario, the next poll action will either miss update 2, or will duplicate update 1, depending on if you use
>
or>=
in your query. This is not the fault of the code, it's a limitation of the MySql datetime type having only 1 second resolution. This could be somewhat mitigated with MySql v8 as it has Fractional Seconds Support though this still would not guarantee atomicity.The solution I ended up using was creating a
order_changelog
tableThis table is updated any time a change to an order is made essentially numerating every update.
For the client side, the server stores the last ID from
order_changelog
that was sent in the session. Every time the client polls, I get all rows fromorder_changelog
that have an ID greater than the ID stored in the session and join the orders to it.I now am guaranteed to have all the orders since last poll, with no duplicates, and I don't have to track individual clients.