Making progress with Changelogrex
, the “Linux kernel Changelog king”! Today I figured out how to get LiveComponents within a LiveView to update by using PubSub, the send_update
function within a LiveComponent, and the update
function within a LiveView.
When the one2
function is invoked with a Linux kernel version string as a parameter (that is properly validated using a regex), the corresponding ChangeLog is fetched from pub.kernel.org and gets split into commits using the functions of the Changelogr.Parser
module. After that, the commits’ text bodies are parsed asynchronously into separate fields across all CPU threads, and the resulting fields are persisted as a %Commit{}
struct in an SQLite database with Ecto.
After every write to the database a PubSub message is sent to the topic “crud”, to which the Dashboard LiveView is also subscribed. Note that LiveComponents cannot handle_info
, and therefore it makes no sense to subscribe a LiveComponent to a PubSub topic.
The LiveView contains two LiveComponents:
ChangelogrWeb.DashboardLive.CommitTileComponent
andChangelogrWeb.DashboardLive.ChangelogTileComponent
.
They both use the same tile design, with a different title and a different function that pulls the data shown with an Ecto query; in this case, a count of all commits, and the most recent kernel ChangeLog that’s in the database, respectively.
After trying to figure it out by chatting with ChatGPT 3.5, I realized that its knowledge of Phoenix LiveView is hopelessly outdated. Finally, I took a look at the documentation :
While a component may always be updated from the parent by updating some parent assigns which will re-render the child, thus invoking
update/2
on the child component,send_update/3
is useful for updating a component that entirely manages its own state, as well as messaging between components mounted in the same LiveView.
Here’s a video that shows the end result in action:
How it works
The trick to get these LiveComponents to update when the data changes is:
- Broadcast a PubSub message to the “crud” topic using
ChangelogrWeb.Endpoint.broadcast
. - Create a
handle_info
callback in the parent LiveView that receives PubSub messages in the “crud” topic. - Within
handle_info
of the LiveView, usesend_update
to each of the child LiveComponents. - What happens next is that
send_update
triggers the LiveComponent’supdate
function, in which you assign new values to thesocket
struct.
As shown on the video, this updates even across different users looking at the same page (the Dashboard).
And yes, it is overkill to show the number increasing, plus it makes the whole thing much slower. For the practical purpose of not having to reload the page to check if a new ChangeLog and commits have been added, the PubSub message doesn’t really need to be sent with every single commit being persisted; it could be sent with every n-th commit, or simply sent once after all the commits in the ChangeLog have been processed.
Outlook
The reason why this needs to be updated by back-end functions without user intervention is that I plan to poll pub.kernel.org every hour to check for new ChangeLogs; and since pub.kernel.org doesn’t offer an API for accessing the ChangeLogs, I am considering making a GET
endpoint available with Phoenix that registered users could consume.
Finally, the most important features are missing:
- the ability to star specific topics or contributors and receive notifications about what’s been going on, and
- the ability to search across all commits.
I have also “baked in” the use of ollama
through ollamex
in order to enable users to ask standard questions about a commit (ELI5, etc.). However, CPU-based LLM inference is pretty slow, and I don’t know if it would be better than simply copy-pasting the commit body into ChatGPT 3.5 after a prompt. Or, maybe, I could allow users to add their OpenAI API token to the settings, so that those who already pay for this service can use it on this web app. TBD.