loyalty.dev

Adventures in software engineering, as told by the seasoned developers at Ascenda Loyalty

How We Solved a Critical Memory Issue When Ingesting a Large Gzip JSON File in Ruby

In this article, we pull back the curtain on how the team investigated the out-of-memory (OOM) issue, optimised memory usage, and validated it to ensure that our system remained robust as the Gzip JSON file that we ingest continues to grow.

From Rails to the Cloud: Demonstrating a Hacking Path on a Rails Application to Kubernetes and AWS

At Ascenda, security is paramount. We continuously enhance our knowledge to stay ahead of evolving threats. In this blog post, we explore how attackers can compromise web applications and their underlying infrastructure.

Optimising Code for Large Batch Runs

Our program enables the exchange of loyalty points, and one of the methods we utilise is SFTP. In order to accommodate a new SFTP partner with a higher exchange volume than usual, we conducted load testing and optimisation on our system.

Postel’s Law - Deriving Robustness from Data in our Networks

Postel's Law: "Be conservative in what you do, liberal in what you accept from others" is a simple trope about adding robustness in disparate systems. It's also a sublime tenet in how we elicit simplicity out of this diaspora to design stable processes.

Risk management for live partner projects

Find out how our team managed risks in an existing live partner project using various tools and processes.

Enabling textual search of encrypted personally identifiable information (PII)

In recent years, there have been many news reports of security breaches involving personally identifiable information (PII). In this article, we describe our solution to managing encrypted data records whilst enabling searches based on customer PII.

Upgrading Hanami, part 1: migrations

The first little step on our journey to upgrade our Hanami 1.3 services to Hanami 2.0. This article opens a series of posts related to upgrading Hanami projects. This time we'll cover the Migrations upgrade.

Returning from transactions in Rails 6, 7, and 8

ActiveRecord provides a simple, block-based API for working with database transactions. Any exception from within the block will roll back the transaction. This works great for simple cases, but what happens if you return from within the block?

Sidekiq prioritisations

Most applications today involve some type of background processing (such as sending notification to a customer) in the form of jobs. Sidekiq is one of the popular background job processor out in the community and we use it extensively at Ascenda.

Data exfiltration via DNS tunnelling

If you've ever wondered whether your sensitive data is sufficiently protected against various forms of exfiltration, you might want to take into consideration a trending attack known as DNS Tunneling.

Anomaly detection with Z-score

Anomaly detection enables abnormal metric trends in your system to be detected by analysing historical data. It is also an effective tool for detecting frauds and mitigating risks.

Operations in distributed apps, part 2: logging & tracing

In our previous post, we gave an overview of our Ops and the challenges of acquiring information for day to day support of the different teams beginning with metrics.

Operations in distributed apps, part 1: metrics

Observability is a topic that appears in multiple disciplines, typically from the engineering, IT Ops or DevOps point of view. Your organisation might also have an SRE team whose engaged with you on this.

Lessons I’ve learnt as a code reviewer

Code reviewing is one of the most underrated topics in software development. When done correctly, it can be a key element in the development cycle and help teams maintain a cleaner code base.

Stop trying to please RuboCop

RuboCop can be a tremendously useful tool, but despite being created by some very smart people, it itself is not that smart, and treating it as if it were can often lead us astray.

Trim your inheritance tree, one twig at a time

We hear it all the time: prefer composition over inheritance. But when dealing with a legacy code base already riddled with complex inheritance chains, where do we even start?