bboyadao

bboyadao

Need help to map kafka topic to liveview

I have a problem when integrate phoenix live view and kafka.
been a week i spend my free time to learn elixir.
Now i have a normal web app just display realtime data from kafka. i have done with producer from another server side. So now in elixir im using phoenix to serve web app.
the problem is i dont actually know how to map consumers topics data to web display.
im using kafka_ex library.
Please give me some advice.
Thank for reading.

Most Liked

Matsa59

Matsa59

Simply subscribe to a topic from Phoenix live view (in mount).

Read data from Kafka and broadcast the data using Phoenix live view.

All your subscribers will receive the data inside a handle_info/3 function. In this function you will be able to assign data to Phoenix client socket.

If you need some code sample, ask in reply :wink:

If you want to keep you code with no coupling (business side vs web side), you can use Registry.

I wrote a lib that could interested you GitHub - wapitea/event_manager: A simple event manager based on elixir's Registry. · GitHub. It’s more sugar syntax than anything else.

It’s new and document may have some errors. You can read how to use registry for example or simply use it.

Matsa59

Matsa59

I think you should consider 2 parts on your apps.

The first one is the web, you will only deal with web things. You will create your LiveView, handle broadcasted messages …

The second one is your “real backend”, where you put all business stuff like consume kafka.

Then you will be able to focus on what to achieve step by step, instead of trying to do everything in one shot.

Here your goals (suggestion):

  1. Consume kafka message (you can use GenStage here for example, or use any supervised process with a loop system to consume your kafka queue).
    it will create the “consume” loop system. So everytime a new message income to your kafka, you’ll consume it asap.

  2. Create your web page to display your data (at this point don’t use real data, create a “fake” data representation of what you will have / want to have)

  3. Link both together. Basically, you want your “backend” to push information to your web page. A possible solution is use phoenix broadcast system (Phoenix.Endpoint — Phoenix v1.8.8).

You can also use channels but, IMO it’s overkill for your needs. But it’s really interesting to use it anyway.

At every step check if everything works as expected. For the first step, every time you push a message try to display it with a IO.inspect for example.


Here an example of what you can do

defmodule MinigameWeb.CustomerLive do
  use MinigameWeb, :live_view
  @topic_name "test_topic"

  def mount(_params, _session, socket) do
    # don't forget to subscribes to a topic ;)
    MinigameWeb.Endpoint.subscribe(@topic_name)
  
    # Mount will be call 2 times (not a bug, liveview behaviour)
    # so you don't want to consume anything from your kafka queue here. 
    # otherwise some messages will dispear like a "bug".
    # The first one for "rendering the page", the second one to "reach the real data".

    # So assigns only "default" values.
    {:ok, assign(socket, messages: [], query: ""}}
  end

  # here we'll capture all incoming messages from phoenix broadcasting system
  # we don't whant to many code so keep it simple.
  def handle_info(%{event: "new_message", payload: messages}, socket) do
    # you want to replace or append the result ? 
    # take a look at https://hexdocs.pm/phoenix_live_view/dom-patching.html
    {:noreply, assign(socket, messages)}
  end

  def render(assigns) do
    # render things
  end
end

In your backend you just have push the kafka message with:

MinigameWeb.Endpoint.broadcast("test_topic", "new_message", kafka_message)

doc: Phoenix.Endpoint — Phoenix v1.8.8

Every time you pushed a message with broadcast/3 all liveviews that have been subscribe the the specified topic will receive the message. It mean, if you have 3 tabs on the same page (3 sockets so), the 3 sockets will execute the handle_info/2 so the 3 tabs will be updated in real time.

chulkilee

chulkilee

FYI Registry is local - so if you run distributed erlang then you cannot use it since kafka consumer process and liveview process is not in the same node.

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement