top of page
Rocky Mountains
Search

Contributing to open source

  • Writer: Raf Y
    Raf Y
  • Jan 12, 2024
  • 5 min read
ChatGPT's response to "generate a generic image that depicts contributing to open source codebases"
ChatGPT's response to "generate a generic image that depicts contributing to open source codebases"

This is my shameless plug for my contributions to open source. I'm writing about them because I think their stories are interesting, but moreover I think developers should take initiative to enhance & contribute to code and libraries that they use every day. Collaboration is the driver of innovation - and open source collaboration is one of those driving forces. In this post, I will describe two situations where I contributed to open source code. In the past, I've always wanted to contribute to open source, but never knew where to start. I hope these stories will plant a seed and inspire those who have always wanted to contribute to open source!


WooCommerce - front end js hook on order checkout


WooCommerce is an eCommerce platform that sits on top of WordPress. It's popular in that regard - the stats of WordPress installations across the internet are staggering, according to codeinwp.com, 42.9% of the internet runs on WordPress, so it's only natural that a lot of those sites are eCommerce sites.


Back in 2015, I had a friend who contracted me to build a WooCommerce plugin that syncs product data between an inventory management system (lightspeed.com) and WooCommerce. I realized there is a niche need for this sort of syncing tool, so I went ahead and reached out to some folks at WooCommerce and was able to launch it on their 3rd Party Marketplace. You can read more about this project here (and actually buy it here if you are a WooCommerce store owner yourself!).


The main feature of this plugin was to sync inventory when a order was made after checkout. WooCommerce provides great documentation and there are various hooks that you can register with to trigger various logic. One of these hooks is is called "woocommerce_checkout_order_processed" - this hook allows you to run arbitrary code after checkout, which was great for inventory syncing. The idea is that the plugin would make an API call to Lightspeed and decrement the inventory of the product that was just ordered. The complicated part was this - what happens if Lightspeed returns a none-200 error and the decrementing of the inventory failed?


Lightspeed rate limits their API requests, and so on a very busy store where potentially dozens of orders are placed at the same time, then you can quickly run into a situation where you hit Lightspeed's API rate limit and they return a 429. Lightspeed uses a leaky bucket algorithm for their rate limiting. You can think of it this way - with every API request you make, the bucket fills up a little. If the bucket overflows, then you've hit the rate limit. The bucket is leaky, so it will eventually empty out, but you will have to wait for that to happen.


ChatGPT's response to "generate a image representing a leaky bucket algorithm"

Going back to our inventory syncing plugin - we don't want to run into a situation where we can't decrement inventory if we hit the rate limit, especially on busy stores where a lot of orders are being made simultaneously. There are various solutions to this - for example you could build some sort of queue with retry logic, however the WordPress/WooCommerce back-end don't provide great solutions for this out of the box. Additionally, a lot of these online stores are being hosted on a hosted solutions (e.g. GoDaddy or some other hosted service) - so access to back-end infrastructure is limited. The final metaphorical nail in the coffin in regards to a back-end solution is that many of these customers have no technical knowledge and don't want to deal with any technical complications. They want a plugin that just works out of the box - so terms like "redis queues" or "retry logic" is not part of their verbiage.


This is where I started thinking of a front-end JavaScript solution for setting up retry logic. JS is great for this, since it doesn't block the server request, and everything happen asynchronously. The solution I came up with is this:


  1. Let WooCommerce generate attempt to generate an order

  2. Let the plugin try to sync the inventory change with Lightspeed

  3. If we get a 429 rate limiting error, then we can leverage front-end retry logic that taps into the leaky-bucket data we get back from Lighstpeed, and we wait a certain amount of time before we retry

  4. Since this is the front-end, we can also communicate to the user that the store is busy, and that in order for the order to succeed, they need to keep their browser window open and wait a little


You could argue that step 4 is not an ideal customer experience, but given the restrictions mentioned above, this was the best solution I could think of.


I started doing my homework to see if there was a front-end hook or event I could hook into to trigger the above logic. I studied WooCommerce's codebase, and, ultimately I couldn't find anything. I saw there were other front-end hooks for other scenarios (e.g. if for payment gateways), but nothing for order checkout. This is where I started considering forking the codebase, and contributing to WooCommerce's codebase. I already found an existing pattern, so at this point, all I had to do was copy the pattern and introduce a new hook for order checkout.


Here is a link to my PR suggesting a change to the codebase to add a triggerHandler called checkout_place_order_success. I made sure to follow WooCommerce's contribution guidelines - here is a preview of the PR:

Adds a triggerHandler called checkout_place_order_success on a successful order during the checkout process. This allows plugin develops to hook into the JavaScript process that gets triggered on the client side on order checkout.

This already happens for payment gateways here via the checkout_place_order or the 'checkout_place_order_' + wc_checkout_form.get_payment_method() triggerHandlers.

While it is possible to use various hooks in the back-end like woocommerce_checkout_process or woocommerce_checkout_order_processed, the fact that this is happening client side means that plugin developers can trigger various client side logic like manipulating the form or making additional async AJAX requests to update external sources of inventory after an order is successfully completed.

The change itself was very simple - all of it being just a one line change - however the implications are much larger. It will now allow any 3rd party developer to trigger front-end code after an order is completed. The code was reviewed by WooCommerce and merged, and the next day, I was able to update my plugin with the above logic and let my customers know that Lightspeed rate limit errors are now handled gracefully. Moreover - this change seems to have helped over developers and more PRs have been opened referencing this hook since then!


So there you have it - this is the story of my first open source contribution. It was simply just adding a new event/hook that didn't exist before, but it allowed me to implement logic that otherwise would have not been available, and ultimately make the experience for the customer a lot better. I hope this inspires other developers out there to make more contributions to open source codebases and showcases the power of having things be open and transparent!


My 2nd contribution will be posted at a later date, make sure to check back!


If can't wait and are interested in my 2nd open source contribution - here is the PR: https://github.com/weixiyen/jquery-filedrop/pull/54


Thanks for stopping by!


 
 
  • LinkedIn
  • Calendly
  • GitHub
bottom of page