siddhant3030

siddhant3030

Suppose I have two tables in my database. I want to build a service in elixir which should pick data from my database and cache each rows in redis keys.

  • I want to use genserver and supervisor to do this.

Can anyone tell me how do I go about it?

Showing Posts 1 to 9

wanton7

wanton7

Do you really need to use Redis? If it is not mandatory to use it, then maybe just use GitHub - whitfin/cachex: A powerful caching library for Elixir with support for transactions, fallbacks and expirations · GitHub Instead.

lucaong

lucaong

Hi @siddhant3030,
I think that more information about your case would make it easier for people to help you with this:

  • Why is Supervisor and GenServer a requirement? Is this an exercise/coding challenge, or you have specific needs with regards to resilience? If it’s about resilience, in order to design the supervision it’s useful to know how you want the system to react to failures (wipe all cached values, keep the cached values, restart the whole system or only specific parts, etc.)

  • What is the expected behavior of the caching service? When should values be purged from the cache? What is the cache key? How are values retrieved from the database?

  • Is Redis a requirement, or just an idea?

If you just want some starting point, you can have a look at the official Elixir getting started guide, that has a very similar example. The guide walks you through the implementation of a key/value store using various techniques, from Agent to GenServer, Supervisor, ETS, etc. Caching services are usually key/value stores with some logic on top, so that might put you on the right track.

andreaseriksson

andreaseriksson

As @wanton7 suggests, cachex is fine. But I think it works best as a short term cache (like memcached). If you really want something that is still (fairly) easy to use would be to use either a new database table where you precalculate data or a materialized view.

I guess the options are endless.

siddhant3030

siddhant3030 OP

Okay. Wait

lucaong

lucaong

Before I start, is this an interview task or homework? If so, make sure that the company is ok with you sharing it here. It is quite likely that employees of companies working with Elixir hang out in this forum.

That said, there are different ways to design such a service and split up responsibilities, depending on specific cases and needs, but a possible way to start could be something like:

  • A scheduler module, possibly a GenServer, that schedules the cache update task every 10 seconds. Usually, something like that is implemented with a GenServer sending a delayed message to itself with Process.send_after, and reacting to it with handle_info, triggering the task and rescheduling the next message. The actual task logic would be in a different module.

  • A Task to perform the cache update: it should select newly inserted rows from the DB, serialize the data, and save it in Redis. How to select for newly inserted rows depends on the data model. It seems from your description that data can only be inserted and not changed or deleted: if so, you might assign auto-incrementing IDs and keep track of the latest ID that was cached, so you can select every record inserted after the last check by selecting for greater IDs.

  • The Postgres client, the Redis client, the serialization logic, etc. should probably all be implemented in their own processes, so they can be restarted independently in case of a crash

  • The supervision tree will depend on the specific needs and dependencies between these processes

Consider that this is just a guess: designing a real system requires a much better understanding of the task at hand, goals, and constraints than we can have from this short description.

If you start implementing this, and run into specific issues, I am sure that people on the forum will be able to help you with them.

EDIT: this response was based on the message it replies to, before it was heavily edited and basically mostly deleted. Without that context, it does not make much sense anymore… What I wrote here is not the way one would design a caching layer.

andreaseriksson

andreaseriksson

Sounds like it. :smile:

lucaong

lucaong

It might very well be a learning question, I just don’t want people to get in trouble.

siddhant3030

siddhant3030 OP

No. This is part of a project. I want to test a POC for this.

lucaong

lucaong

Then the best would be to describe more clearly the project goals, so people can help you better. What’s the end goal of your POC, or the problem you are trying to solve with it?

I am asking because your description focuses on the what, but doesn’t mention the why, and that makes it difficult to devise a proper solution.

Not knowing what its goal is, the system you describe sounds strange and over-engineered. For example:

• A simple POST API in golang to insert data into your postgres tables.
• Elixir service should pick data in these 2 tables and cache each row in redis keys in every 10 seconds.

Why can’t the golang service write on Redis? That would make the Elixir service unnecessary, simplify the whole system a lot, and the cache would be updated as soon as a write happens.

Alternatively, why should the Elixir service poll the database every 10 seconds, rather than listening to a messaging queue (RabbitMQ, Kafka, etc.)? That would avoid unnecessary database queries, and make the system scalable, as you would be able to add more workers as needed.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews