Looking at this without any experience in writing apps it occured to me that I may avoid both writing out 4 DB and complex method of query/control of booking while yet still being able to let user pick a date and represent all room types and their level of availability by processing reservations stored in users in rooms collection by basically sorting and grouping start and end dates of stays and then pairing them up by iteration to decrement a counter for amount of rooms within those ranges which should have supposedly rid me of necessity in writing booking acceptance protocol and having something more concrete to send to the user. The reason for not sending pairs of start and end dates is in order simplify update operations to availability. Philosophically speaking is this approach any good, and couldn’t I still do the same thing by just by subscribing to original reservations and comparing to amount of rooms.
I haven’t had nearly enough coffee today to try to answer your question, but I’m pretty sure you just won the forums.meteor.com “Longest Sentence Award”. 640 characters - not bad!!
Well first of what I was going to do is straight up represent availability through inserting new reservations without owners and then have clients subscribe to that. I then couldn’t help not feeling bothered to right function that takes into account room types and amounts and current reservations while then having to deal with writing a template for each room type for submitting said reservations under current user using session date from datepicker.
BTW try adaptovit “адаптовит” which is what they put in soldier rations for Russian army. It doesn’t so much alerts as invigorates you, and coffee is nowhere close to being as addictive in which case as effective if using that as a metric. Isn’t redbul either.
Wow, count me in!!
If you want a foolproof (hopefully) method to handle product availabilities in Mongo, this is a workflow I have thought out, and will get around to implementing in Meteor when I get smarter.
- product collection
- allotment collection with
You store one allotment record per sellable product. If your have a hotel room with an allotment of 5 on the 1. January 2017 then you would store 5 records for the 1. January 2017. The number of products for each allotment record is by definition 1. If you are a hostel and sell bunk beds and not rooms, each bed has an allotment per day. If you are selling seats on a plane, each seat has its own allotment record per day and flight. In essence you store the smallest sellable entity in the allotment table. The allotment table will get pretty huge over time, but with indexes and tasks that move old allotments into history collections this ought not be a problem.
If a workflow wants to book a product/room on a specific date, you search for one allotment record by product_id and date, and write the locktimestamp. If you cannot write the timestamp, then this allotment item is in use by some other process. If you can write the locktimestamp then you can work with this allotment. As Mongo has document level locking, you can be sure nothing can go wrong here. Either you can lock a record and work with it or not. The timestamp you write defines the time when the record can be automatically unlocked again. The length of time you allow the locking of a record will depend on your use case. If you need to book two rooms for 7 nights, you need to lock two allotment records on each day and will have to lock 14 allotment records. If you can’t do this, then you have to try again or tell the user that no products are available.
After you lock an item you can write the order item_id, for example, and then remove the locktimestamp. Any allotment item that is assigned to an order item cannot be used by another process.
A background task regularly searches for allotment records that have a locktimestamp < current timestamp, and unlocks these records.
In essence this is a workflow that one uses for theater ticketing software. If you start incrementing and decrementing one record, you lose the ability to uniquely identify which allotments belong to which order items. You would have to implement some form of logging, so that you know which order item actually caused the increment/decrement of the allotment, and as Mongo does not allow multi document transactions, at some stage you will get bitten badly. Even with an ACID compliant database you can still have problems if your code is not foolproof. Been there, and experienced the problems with bad allotments. It is no fun if a customer is at the airport and the flight is overbooked, or at a hotel and the hotel has already booked the room for someone else.
If you need the total number of rooms still available in your frontend, before you write the item_id, write a task to a collection that will calculate the number of unbooked products on a specific date. This task will update a view collection that stores this information. The data in this collection is only for display purposes. If a locktimeout is reached and an allotment is returned to the pool, then the collation task is executed. If a product is booked, then the collation task is executed. If an allotment status for an item in an order changes the collation task is executed. As long as the collation task is executed, your summary table will contain the correct rest allotment, even if it takes a second or two to get up to date. And because you do not rely on the summary table for your allotments, you can’t overbook, and even though Mongo does not have transactions you can still be pretty sure that your allotments work. Your frontend subscribes to the summary table, and magically when a product is booked your frontend shows the changes allotment.
Perhaps there is another better workflow to work with allotments, but this would be my suggestion.
I am about to start working on a meteor booking engine shortly. If others are trying to solve the same problem perhaps we could start collaborating on a package to solve this very common scenario. Would be helpful to have a few people bring their past experiences to the table.