#41 Bukalapak X JakartaJS Notes

Topic: async_hook and Progressive Front End Transformation of Bukalapak

This week, I attended a meetup from JakartaJS. This is the 41st meetup of this community. So what’s there?

Contents

This post contains summary from this meetup, which consists of these 2 main topics:

  • Async hooks, new Node feature in its version 10.x.x (cmiiw)
  • Bukalapak Front End Transformation

Async Hooks

This topic brought by Ahmad Rizqi Meydiarso, engineer from Kata.ai. This topic was brought usdeeply into Promise implementation and understanding the event loop.

Rizqi while presenting some brain quest about asynchronous handling. Photo from: Personal Documentation

Async hook is new to NodeJs, as it was shipped along with NodeJS 10.9. As the name express, this library provide us to inject hooks inside asynchronous process inside NodeJS (which we often use in `Promise` or `setTimeout`).

Background: Untraceable asynchronous errors.

Rizqi said that the pain in Promise error logging is its stack trace is not helpful at all. Synchronous error don’t behave like this because the operation runs in one execution, and it doesn’t run in different context.

Let’s see this example. Synchronous code below read as follows:
foo() invoke bar() invoke foobar() which throws Error .

Beautiful stack trace, we know who throws what and who triggers that. Credit: Rizqi’s slide

However, in Asynchronous Error, the error isn’t as informative. For example, here we change implementation of direct invoke to setting direct timeout ( setImmediate(fn) is the same with setTimeout( fn, 0 ) ).

Wait, what? Which one failed? Credit: Rizqi’s slide

It only shows which line throws the error. It didn’t show who triggered. Imagine this stack trace in your production log, and respective line was used by almost every component in your system and the server is scaled, using micro service architecture.

Thinking quick of this problem, passing some information of who’s calling to every Promise we have sounds solve the problem (despite the poor pattern sorry Uncle Fowler). Very simple, but however, isn’t there any sweet solution for this?

Async_hook comes handy.

async_hooks API essentially makes it easier for you to track your resources. By resources, I mean everything you could put in a variable (cmiiw). Think of async_hooks as resources wrapped in callbacks regarding to its lifecycle events: init , before , after , destroy. More on this in the documentation.

Implementation

So, to solve our previous problem, we create a middleware called tracker.

Creating middleware using async_hook to track Uncaught Exception. Credit: Rezqi’s Slide.

This is the snippet of createTracker. Let’s walk through it.

  • It creates a closure which contains an array contexts and the hook asyncHook.
  • In line 24, every time a new request comes to our middleware:
    we create an id from executionAsyncId in line 25
    and set contexts[id]to req (yes, raw express request object) at line 26
  • In line 7, the init block of our async_hook.
    Since there are so many events trigger this block, we wisely filter to process requests (the if statement on line 8).
    How does it know?
    By checking whether the triggerId index is set in the contexts (which is set in previous point)
    If set, we set the contexts of new asyncId (different resources & events, different asyncId, but if same trigger, same triggerId) to the same value (contexts[triggerId]).
  • In line 19, we create a listener for Uncaught Exception .
    We find the executionId from respective error, and find the culprit by accessing the request path from the contexts array (by access contexts[id].path )
  • In line 12, whenever a request resolves, it deletes the contexts of respective asyncId.

Pretty clear? Now let’s use it in our express app.

Using our tracker to express app. Credit: Rezqi’s slide

And how does it go? Perfect, it logs the path of respective error request. Great!

It shows which path throws error. Credit: Rezqi’s slide

Basically, that hook could be anything, since you can trigger anything when your hook invoked. However, it is very important to keep our hooks simple, not complicated and not do another asynchronous function (otherwise, will become a infinite loop).

The sweet part here is we don’t have to customize our promise to use this async_hook. So our promise only deals with logic, and our tracker deals with tracking resources. Uncle Fowler will be proud.

PS: This API is still experimental.

Bukalapak Front End Transformation

Like common transformation phases, it cames from gigantic monolithic system where front end and back end tightly coupled. Then, they starts the journey of separating concerns of both as you can see in their slide. This topic brought by Rama Dimasatria, Senior Front End at Bukalapak.

Rama explaining 4 concerns of front-end development and become critical points of the transformation itself.

In this part, I’ll just jump into big points that I think very interesting to discuss. Let’s go!

Problem Introduction

Let’s have a little imagination of how micro front-end could solve the problem (this is my wording on what problems does micro front-end solve, not from the presentation)

We comes from eCommerse site that uses server-side rendering page where everything comes at once.

In this page, there are three concerns. How to make them not editing the same file, or even not in the same repo? Credit: https://micro-frontends.org
  • If just a slight bit of checkout button changes, should I redeploy all front end servers?
  • We work in scrum spirit, separated in squads, and each squads assigned different concerns (Searching, Landing Page, Checkout, Most Bought Item, etc are concerns). Should we work on same repo, crashing merge requests on one another and slowing down development?
    No isolation development & concerns separations
  • Production bugs! Who deployed our big front end recently? Other squad! It must be their fault!
    No isolation deployment & Volatile Deployment
  • (in sprint planning, discussing sprint story)
    A: I think using React Component will be useful on developing this story
    B: But our project is using Angular.
    A: … okay
    Doesn’t support different technologies

Micro Front End

As the speaker said, this concept was adopted from micro service. Instead of APIs, these services provides elements. So there will be service providing headers, contents, footer, and all of them are curated based on the page (is it checkout, or just landing page?) through proxy.

Illustration of how micro front-end implementation. Credit: Rama’s Presentation

How does it solve the problems?

  • If just a slight bit of checkout button changes, should I redeploy all front end servers?
    Answer: I just need redeploy the button in Checkout service, that’s all
  • Squads are assigned different concerns. Should we work on same repo?
    Answer: As micro front end are separating elements on different services, means it can be separated on different repos.
    Goodbye conflict!
  • Production bugs! Who deployed our big front end recently? Other squad! It must be their fault!
    Answer: Isolation development, we didn’t touch other code (for styling, use BEM convention to avoid conflicts).
  • (in sprint planning, discussing sprint story)
    A: I think using React Component will be useful on developing this story
    B: But our project is using Angular.
    A: … okay
    Answer: Remember, different concerns: different services. Which means even in the same page, it is possible to use several tech stacks for one page, since they are based on the services itself.

PS: Blibli also posted about their micro front-end architecture in their engineering blog.

References

See you on the next meetup! Credit: Bukalapak Documentation

Hello!

Thank you for reading this post. If you find this interesting, don’t hesitate to clap on this post and read more on my publication list.

If you have any questions of doubts, drop some comments and let’s discuss about it, or mail me at ronayumik@gmail.com.

Have a good day! 😃

Regards
Rona

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade