Skip to content
This repository has been archived by the owner on Jul 24, 2020. It is now read-only.

[Fix Cart Latency] Design specs for newly architected cart functionality #586

Closed
squidgetx opened this issue Jun 26, 2014 · 10 comments
Closed
Milestone

Comments

@squidgetx
Copy link
Contributor

PROPOSED WORKFLOW

  • CartReservations is no longer a thing
  • Cart no longer autosubmits info for validation (or only validates for dates?)
  • "Check availability" button exists to refresh catalog (?) and to set flash notice if items are not available for new dates
  • Reservation 'new' view (finalize reservation view) shows calendar availability of items (if items are not available for submitted dates)
@squidgetx squidgetx changed the title [Fix cart latency] Design specs for newly architected cart functionality [Fix Cart Latency] Design specs for newly architected cart functionality Jun 26, 2014
@squidgetx squidgetx added this to the 3.3.0 milestone Jun 26, 2014
@squidgetx
Copy link
Contributor Author

New Cart Model

  • start_date
  • due_date
  • reserver_id
  • Hash of equipment models and their quantities: the EM's are the keys and the values are the quantities. This will make it very easy to draft an 'available?' declaration
require 'spec_helper'

describe Cart do

  context "General validations" do
    it { should validate_presence_of(:reserver_id) }
    it { should validate_presence_of(:start_date) }
    it { should validate_presence_of(:due_date) }
    it "should validate that start date is < due date"
  end

  describe ".initialize" do
    it "has no items"
    it "starts today "
    it "is due tomorrow"
    it "has no reserver"
  end

  describe "Item handling" do
    describe ".add_item" do
      it "adds an item to the array"
    end

    describe ".remove_item" do
      it "removes an item from array"
    end
  end

  describe ".empty?" do
    it "is true when there are no items in cart"
    it "is false when there are some items in cart"
  end

  describe ".prepare_all" do
    it "returns an array of reservations"
    describe "reservations in array returned" do
      it "inherits the cart start date"
      it "inherits the cart end date"
      it "inherits the cart reserver"
      it "inherits the cart items"
    end
  end

  describe ".purge_all" do
    it "empties the cart"
  end

  describe ".models_with_quantities" do
    it "returns a hash of models as keys and quantities as values"
    #do we really need this?
  end

  describe ".check_availability" do
    context "items are good to go" do
      it "sets the flash to success"
    end
    context "items are not good to go" do
      it "sets the flash to detailed error message"
    end
  end
end

@squidgetx
Copy link
Contributor Author

Current workflow for adding an item to the cart

  • Add to Cart button sends a PUT request to /add_to_cart/:id
  • /add_to_cart/:id is a custom route that goes to catalog#add_to_cart
  • catalog#add_to_cart calls catalog#change_cart(:add_to_cart, :equipment_model)
  • which finally calls cart.send(:add_to_cart, :equipment_model)
  • validateSet is called on the cart
  • A redirect to the root path is called
  • A render js action is called on "update_cart"
  • Div list_items_in_cart is refreshed with $('#list_items_in_cart').replaceWith('<%= escape_javascript(render :partial => 'reservations/list_items_in_cart') %>');
  • Flashes are cleared/reset in a similar manner

Proposed Changes

  • Obviously, don't call validateSet
  • Use pure jQuery or other frontend to update the list items div instead of using a render partial. This should reduce the server load, though it's unclear how it would fit in easily in the current workflow

removing is similar

@squidgetx
Copy link
Contributor Author

Useful links, perhaps

@squidgetx squidgetx modified the milestones: 3.4.0, 3.3.0 Jun 27, 2014
@shippy
Copy link
Contributor

shippy commented Jun 30, 2014

Note of caution: the only thing that ReservationsController#create takes from in-database CartReservations is equipment-model IDs. It takes start date and due date from params[:reservation], which is a hidden field on the submission page. As this is expected behavior in the refactoring, I just wanted to document it here.

@squidgetx
Copy link
Contributor Author

What if we simply split up the validations between the fields that they're relevant to?

  • When a user changes a date, it autovalidates only for availability and blackout dates.
  • When a user adds/removes an item to the cart, it validates for max-model count.

If we remove cart reservations and write custom methods to check these validations (that take arrays of equipment model id's or something as arguments instead of reservation objects) I think it has a chance at being fast enough.

@squidgetx
Copy link
Contributor Author

Update cart spec and model are on branch 587_fix_cart_latency

@squidgetx
Copy link
Contributor Author

  • Cart model and spec
  • Convert cart to be stored in CookieSession as opposed to regular session
  • Remove cartReservation model and entry in database
  • Disable (do not remove!) autosubmit class from cart date form
  • Re-route make-reservation button to new reservation view
  • Refactor new controller action to use cart.prepareAll and validateSet
  • Refactor validations code
  • Refactor equipment list div in cart form

At this point we should have a working, fast cart that doesn't autosubmit its data fields for validation. Discussion of what options from here should go in #586.

  1. Reimplement choice autovalidations. We may have made things fast enough that the light and important validations run quickly enough to not be a distraction to the user. On date changes, we could run available and blackoutdate validations, and on item adding/removing we could run max_count type validations. This would most closely resemble our current workflow.
  2. Reinvent the reservation confirm page a la Allow changes to reservation on Create Reservation page #237. We could also add some form of calendar view (Calendar View of item availablity #12) so the user has all the information he/she needs to edit their reservation. This would offer the fastest workflow for users: after the user has added all their equipment, they only need to go through typically one more page (the confirm page) to finalize their reservation instead of hunting for valid dates via constant form resubmission.
  3. Add a check-availability button to the cart, by the Make Reservation button. This has the advantage of being quite easy to implement but is probably the least user friendly

These three options really aren't mutually exclusive, though I think that if we implement 2, both 1 and 3 are unnecessary, and similarly if we implement 1 we don't need 3 (and vice versa)

Discuss here. (@shippy, @dgoerger @mnquintana @orenyk ).

@squidgetx
Copy link
Contributor Author

SOME BENCHMARKING

using some js timestamps created at points when the cart would pause and resume we can actually benchmark which parts of the cart updating takes so long (ActiveAdmin routes disabled)

  • Changing the start date (range 1-5 days), no items: ~1500ms
  • Rendering the catalog/models_available partial: ~800ms
  • Rendering the cart_dates partial: No significant change (note, did not seem to affect application behavior even when disabled! investigate this further)
  • Changing the start date (range 1 day), 1 item: ~1700ms
  • Changing the start date (range 20 days), 1 item: ~5000ms

(note in the above scenarios the user has 0 other reservations)

@squidgetx
Copy link
Contributor Author

Are front end validations possible?

  • Full Front End Every reservation for every equipment model and every user is given to the client at the initial load of reservations and stored using HTML5 localstorage. This has the advantage of probably being quite fast. It's also kinda janky, questionable security-wise, andhas the potential for being a whole lot of data. We would also have to duplicate code we already have in the reservations validations.
  • Front End Dates Run availability/blackout validations in the client only when the dates are changed, using a set of data built from the server of the reservations for the relevant equipment models and reservers. This is less data than the full front end option but there will be a lag when adding items or changing the reserver (not nearly as bad as it is now, though) because the relevant reservations will have to be re-built on the server and sent to the client. Reserver ids and equipment model hash is stored in the session. Again, there will be front-end back-end code duplication
  • No front end validations without CartReservations Keep the workflow largely the same, however instead of validating CartReservation objects we simply run select custom validations on the cart (eg, valid cart?) This will duplicate logic from the reservation validations. Alternatively we could build reservation objects and validate those instead.

@squidgetx
Copy link
Contributor Author

Since we made such great progress in #628, I don't think we need to implement such drastic changes. After we finish #574 and #573 I think we'll be good to go on the cart.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants