• Tree Reconcilation

    React calculate what the DOM should look like (called “Work-In-Progress”) and what the DOM currently looks like (called “Current”), in virtual DOM DOM (js object). Those were represented as two branches of object trees.

    After making those trees, React compare those two branches and find minimum number of step required to make WIP into Current.

    Server Rendering

    Traditionally, after server generate complete HTML string from component and send to the client, js code for that same component also has to be sent to the client so the Virtual Dom could be build using that function component.

    Now here’s where React Server Components kicks in. RSC add the ability to mix server component and client component without having server to send server components code to client. How does React do that? we will explain in the next section

    Flight

    In order to add VDOM from server component without sending component code, React added ability to serealize React Element Tree returned from server executed functions. The result of server component is serealized and then sent to the client.

    Let’s suppose we have a following code in nextjs.

    export default function Home() {
      return (
        <main>
          <h1>understandingreact.com</h1>
        </main>
      );
    }
    

    The above code will be serealized into the following, this process is called “flight”.

    "[\"$\",\"main\",null,{\"children\":[\"$\",\"h1\",null,{\"children\":\"understandingreact.com\"},\"$c\"]},\"$c\"]"
    

    These sum of data sent is called “RSC payload”.

    If we format it for easier examination, it looks like this:

    {
      "type": "main",
      "key": null,
      "props": {
        "children": {
        "type": "h1",
        "key": null,
        "props": {
          "children": "understandingreact.com"
        }
    }
    

    While React provides serealization format, meta-framework (eg: Next.js) must do the work of creating/sending payloads. Next.js, for example, has a function in its codebase called generateDynamicRSCPayload.

    This post is the brief summary of the following source: Understanding React Server Components

  • Not too long ago, I had a competition held within university. It was web-app related and I was supposed to re-design Winnipeg-CrimeStopper website. It was mostly front-end related and I’ve had a lots of fun designing the website.

    Now that I got the AWS-SAA certificate, I wanted to host this using my AWS knowledge. As said in the movie, “Oppenheimer”, theory will only take you so far.

    Before I begin, I needed to figure out architecutre. Since this is just my side project and I was expecting low traffic. Serverless architecture was the best cost-efficient architecture I could thought of. Here’s the list of service I was gonna use:

    Aurora Serverless v2 for DB

    Lambda + API Gateway for api request

    S3 for static image file

    ECS fargate for web-app deployment

    First thing first, I was setting up Aurora instance in AWS. But before I initiate my instance, I went into the pricing page of Aurora and found out, while Aurora Serverless v2 does automatically scale from 0.5 ACU to 5 ACU Aurora Serverless v2 techinically incur an idling cost (because it doesn’t scale down to 0 ACU). This implied I had to pay around 40 USD per month minimum.

    This didn’t feel much of economical. Besides, I have more and more projects coming so spending $40 monthly just to deploy one project was a bit too priecy for a full time university student making negative wage per hour ;_;

    So I needed to come up with alternative. Then I remembered I could use DynamoDB, I quickly went ahead and looked up a pricing

    “$0.125 per million read requet units”, this statement alone instantly made me so happy. I can afford that! yay! (But going from RDBMS to NoSQL implies code change and oh no refactoring is so fun)

    Anyway, now that we take care of this, I set up my lambda function for retreving criminal’s data, and hook it up to API gateway so I can later fetch this data from my web-app.

    And I tested the api using command line

    After which, I was trying to see if my website works on my local environment; it didnt. It was not fetching data at all. So I looked up the web console and realized I didn’t configure CORS for my api gateway so browser was blocking my request by Same-Origin-Policy

    After configuring CORS, web-app on local was working as intended. Now I needed to deploy it.

    I was going to

    1. containerize

    2. and have ECS use that containerized image

    buuuuut… deploying react app using vite was rather … time consuming- I wanted to finish this whole deployment within 24 hours otherwise I wouldn’t have time for it. So I needed to find an easier solution.

    That’s when I stumble across AWS amplify. It is fully managed service by AWS and all I had to do was to link my github repo into this. So I linked it, waitied, and …

    build failed … which was surprising, because “it works on my machine!”

    So I tried to dig around looked for a build log

    …oh

    For some reason, it was running on outdated node v18.20 when it needed to use node v20 or above.

    So I went into Build setting -> Advanced setting and match the node version to the same version I’m using on my local machine.

    Then finally, finally it worked !!

    After confirming deployment, I went to Route53 and purchased domain so it’s more easily recognizable. Here’s the full website.

    https://crimestopper.click/

  • ohhh I just got the email from AWS saying that I passed the exam. And this is midnight and I get this dopamine rush and I can’t go to sleep now lol. I worked really hard for this and seeing the result come into fruition really does make me feel good.

    I learned so much during this journey and now that I know “some” of the aws service (because there are still lots I don’t know lol – aws has 200+ services ). I want to use this knowledge and apply this to my side project. And I’m not talking about using one or two services from AWS, I want to design the whole architecture using AWS.

    One of the thing that comes on top of my mind is serverless architecture. Low management overhaed and High scalability sounds too good to be true, so I’m gonna try to apply it for myself and see theory applies into practice.

    In terms of what to make, I do have several ideas but I’ll save that for another post. For now, I got some university works to do (Fall term started :( )

  • Snowball:

    • Ordered from AWS, Log a job, Device Delievered (not instant)
    • Data Encryption use KMS
    • 50TB or 80TB Capacity
    • 1 Gbps or 10Gbps Netowrk
    • if storage is between 10 TB to 10PB, then it’s within economical range, if more, then order multiple Snowball(?)
    • can send multiple devices to multiple premises

    Snowball Edge:

    • Both Storage and Compute
    • Larger capaciy than Snowball
    • 10 Gbps, 10/25, 45/50/100Gbps
      Edge has multiple mode, that is
      Storage Optimized (with EC2) – 80 TB, 24vCPU, 32 Gib RAM, 1 TB SSD
      Compute Optimized – 100 TB+7.68NVME, 52 vCPU and 208 GiB RAM
      Compute with GPU – as above, but with a GPU

    Snowball is purely for storage, Edge include compute
    use Edge when data processing or data ingestion is neededd

    Snowmobile:

    • Portable Data Center within a shipping container on a TRUCK (super cool)
    • ideal for single location when 10PB+ is required
    • Not economical for multi site or sub 10PB
  • Simple Queue Service

    • Public, Fully Managed, Highly-Available Queues – Standard or FIFO
    • Standard guarentee at least one delivery, order is not maintained, FIFO guarantee exactly once, order is maintained
    • Messages up to 256KB in size – link to large data
    • Received messages are hidden (VisibilityTimeout) then either reappear (re-try) or are explicitly deleted
    • Dead-Letter queues can be used for problematic message
    • ASG can scale and Lambdas invoke based on queues length
    • SQS billed on ‘request’, 1 request = 1-10 messages up to 64KB total
    • Encryption at rest & in-transit

    SQS Standard vs FIFO:

    FIFO:

    • FIFO is 300 TPS w/o Batching, 3000 with
    • need FIFO suffix for FIFO
    • message is delivered exactly once

    Standard:

    • Standard is like multilane highway, near unlimited TPS
    • faster
    • order is not guarenteed
    • message can be delivered more than once

    SQS Delay Queues:

    • make message hidden for x amount of seconds when added to the queue
    • this is unlike VisibilityTimeout where message is hidden upon being received by consumer

    SQS Dead-Letter Queues:
    Imagine process that keeps failing, we need a way of handling this, this is where Dead-Letter Queue comes in. When ReceiveCount > maxReceiveCount & message isn’t deleted, it’s moved to Dead-Letter Queues.

  • RDS has two type of backups; Automated, Snapshot, both of which is stored in AWS-managed S3 Bucket (you can’t see them within your S3).

    Because S3 is regionally-resilient, backup is also reslient.

    How backup works – Snapshots:
    Snapshots aren’t automatic, you run it by script or manually. They function like EBS snapshot. First copy is the full copy of DB, and then incrementer after. Whenver snapshot occurs, there’s a breif moment of interruption (this may impact your app if you’re single AZ).

    Automatic backup:
    happens once a day. Think of it as automated backup.

    Retention period:
    amount of day you can recover your data up to; eg: 35 retention period allow you to recover data 35 days ago

  • EC2 Placement Groups
    This is how we can specify each instance physically be apart or stay closer to one another

    Cluster Placement Group – Pack instances close together
    Spread Placement Group – Keep instances separated
    Partition Placement Group – Groups of instances spread apart

    Cluster Placement Group:

    • Can’t span AZs – One AZ only – locked when launching first instance
    • Can span VPC peers – but impact performance
    • Require a supported instance type
    • Launch at the very same time (not mandatory but recommended)
    • 10 Gbps single stream performance
    • Performance, fast spee,d low latency
    • Likely on same rack

    Spread Placement Groups

    • Provide infrastructure isolation
    • each rack has its own network and power source
    • 7 instances per AZ (HARD LIMIT)
    • Not supported for dedicated instance or host
    • Use case is usally for keeping small number of instances that needs to be separated from each other

    Partition Placement Groups

    • 7 Partitions per AZ
    • Instance can be placed in a specific partition
    • great for topology aware applications

  • Horizontal vs Vertical Scaling

    Vertical Scaling:

    • Just buy better instance lol
    • However, this require a reboot – disruption
    • Larger instances often carry a $premium; not cost efficient
    • There’s always an upper cap on performance
    • no app modification required, relatively simpler than HS

    Horizontal Scaling

    • just buy more instance
    • load balancer may be needed
    • No disruption when scaling
    • no real limit to scaling
    • often less expensive – not having to involve large instance premium

  • Problem with virturalization is that guest Operating System taking up too much space. This becomes rather wasteful when we’re horizontally scaling, and have multiple of instance, we’ll be essentially have same OS on each instance that are not doing anything useuful.

    SO HERE COMES CONTAINER

    we still have host hardware, and host os, but we have container engineer and have multiple apps running. It’s more condensed than virturalization.

    Docker Image:
    This is what container is made of; layers of images. And they’re readonly; they never change after they’re created. So special Read/Write layer is populated which allow them to read/write app(?)

    Container Registry:
    You can use docker hub to upload your container or download other’s container.

    Key concept:

    • Dockerfiles are used to build images
    • Portable, self-contained, always run as intended
    • Lightweight; parent os used, fs layers are shared
    • Container only runs the application & environment it needs
  • ECS has two mode; ec2, fargate.

    ECS orchestrate how container should be managed.

    ECS create cluster; it’s where your container run from.

    You need a way to let ECS know how you want to run container images which image will be located in registry.

    To tell ECS about your container image, you create container definition; provide just enough info for a single container.

    Then we have task definition; it represents what application stores(?). Task definition also save task role; iam that task can assume.

    Service definition; how we want container to scale, how we’d like our task to run, can run load balancer.

    (ok I’m gonna be honest, idk what they’re talking about lol maybe have to do demo myself)

    To summarize:
    Container Definition – which Image to use & which Ports exposed
    Task Definition – Security (iam role assume), Container, Resources (what will our task consume?)
    Task Role – IAM Role which TASK assume
    Service – How many copies, HA, Restarts