Live data from Hacker News

Lovely Week with Elixir

ramblingcode.dev

131–139 of 139 posts

Re: Lovely Week with Elixir

#131
post #23
post #6

Earlier quoted context omitted.

Dude, LiveView is wild . It feels kind of magical, and I think people are gonna start adopting slowly, then all at once. There's an awesome blog post on their website. where Chris McCord, creator of Phoenix, builds a real-time Twitter clone in 15 minutes. https://www.phoenixframework.org/blog/build-a-real-time-twit...

I've been watching Elixir/Phoenix/LiveView from the sidelines, reading just enough to salivate a little but still left with the feeling that my use-cases wouldn't be adequately covered by it. Which kind of SPAs wouldn't work well in LiveView? I'm working on an app in Ember right now where a lot of data is fetched by the client asynchronously and then either showed once its fetched or only when the user pushes a butto…

The biggest "homerun" case for LiveView is all of the forms where you'd typically do server side rendering then add a bit of JavaScript for the few dynamic pieces you need. Think about what you might typically see in a Ruby on Rails app. Lots of Ruby generating the views, a bit of JavaScript for client-side whatever.

LiveView can be used for way more than that, but I think replacing "glue" JavaScript is the most slam-dunk case.

Re: Lovely Week with Elixir

#132

The job market for Elixir is pretty small. Sure, there are a couple of people here responding with specific listings, but still. I was hoping it would have ramped up by now but it seems that it's going to stay a niche player.

I think it's healthy but small, and growing.

Re: Lovely Week with Elixir

#133
post #109
post #24

Earlier quoted context omitted.

> 1. Ecto is simply the best DB library I've encountered in any language. I'd almost recommend learning Elixir just to be able to use Ecto. It's interesting, people always talk about Phoenix, which is nice, but Ecto is really special. I often recommend it to anyone who is feeling burned by Active Record implementations.

I thought so too, at first, but now I'm really down on it. Ecto Changesets work fine for flat data, but when you have to deal with nested data, it becomes a nightmare, because you have to use these special functions to read and update the data. Doing that in a nested context just gets really clunky, especially coming from Clojure, where I would just do something trivial, like (assoc-in changeset [:children 1 :title]…

That is indeed a bit of a pain point. From what I understand, it's a bit intentional and the library authors want you to prefer flatter data structures. Now of course not all structures CAN be flat so you can hit a bit of an impedance mismatch. However, I think Ecto is amazing for more common (for me at least) cases.

Re: Lovely Week with Elixir

#134
post #24

Earlier quoted context omitted.

> 1. Ecto is simply the best DB library I've encountered in any language. I'd almost recommend learning Elixir just to be able to use Ecto. It's interesting, people always talk about Phoenix, which is nice, but Ecto is really special. I often recommend it to anyone who is feeling burned by Active Record implementations.

Having worked for years with both Ecto and Ruby's ActiveRecord I really prefer ActiveRecord. It's less flexible but so much easier to use. Ecto is somewhat closer to SQL and still suffers from the "I have to relearn how to do SQL in yet another language" syndrome and it's a particularly difficult case of it. A lot of boilerplate to represent database tables and a lot of not obvious code to do easy queries. Definitely…

I can definitely see where this criticism comes from. There is a lot of extra data description, and an abstraction that leans towards SQL.

However, that "boilerplate" makes data access and return values super clear. It also allows you to segregate Ecto queries by domain, meaning in a User context you may only have access to certain fields, whereas in a data processing context other fields may be available. This is great for coarse table access control, and you get it almost for free. It also allows you to very easily validate data at the edges of the system.

As for the query language, I can say for sure that there's a learning curve but it's close enough that your 1st guess is usually correct in my experience, and it removes a lot of foot guns like n+1 queries by default.

TL;DR there's some learning curve and extra LOC to write, but you get a lot in return.

Re: Lovely Week with Elixir

#135
post #78

The BEAM is a huge win: having lightweight threads means you can often do away with things like Redis for job queues and PubSub stuff. I love this answer on StackOverflow by Elixir's creator: https://stackoverflow.com/questions/32085258/how-can-i-sched... So simple. Something that would require a job queue and a job runner fades away into a piece of the OTP application tree. When it crashes, it will even come right b…

How is that stackoverflow answer good ? You lose everything about the scheduled jobs when your app crashes. This doesn't even address the rampant memory leak issues that plague long running genservers.

Some jobs don’t need persistence, or might have everything about them stored in a Postgres DB. Examples: I have a project where I render lots of little PDFs as previews for a LaTeX editor. My use case means it’s good to keep them around for a short while; after an hour or so I want to delete them all so they don’t fill up my disk. Perfect case for this. The question mentions rebuilding a site map—that sounds like it doesn’t need to persist much state. Finally, at my work we have orders that sit in a Postgres DB that we regularly check to see if any are stuck. We do use the Quantum library for that, but a solution like this could theoretically work.

> Rampant memory leak issues

As long as you’re not sending this genserver bogus messages, I don’t see how memory would leak in this example. Erlang applications are known to run uninterrupted for years at a time, so I figure this is a solvable problem.

When you do need persistence for more robust job scheduling, yes, having a real queue system in place is much better. You are correct there. I think the answer is good because it is so small and fits these simple use cases—the fact that you can handle those cases without needing something heavier is pretty awesome.

Re: Lovely Week with Elixir

#136

Earlier quoted context omitted.

It's not too late. You can write your own wrapper around the :gen module, and if it's really good maybe people will adopt it. I will say one thing:. If you are thinking of BEAM processes as actors/(Kay objects), you're missing the real meat of what makes BEAM processes special; what they really are are atomic units of failure domains . The other stuff is just a useful analogy that lets people grok the code structure…

We have very few GenServers in our system, with their supervisors to keep them alive and read back the initial status from the db in case of failure. They're not object in the Ruby or Python or Java way. They really are servers that take care of a specific action. The vast majority of code is function calls in the main process of the system. Still I'd like to be able to program the GenServer in a more understandable…

Yes. Genserver is quite frankly a mess. I just want to discourage pushing that object metaphor. Have you seen the Dave Thomas ornery video where he calls a genserver a dog's breakfast?

https://youtu.be/6U7cLUygMeI

Re: Lovely Week with Elixir

#137
post #63

Earlier quoted context omitted.

Having a queue means you have a distributed system. How do you handle network problems, errors/retries, back pressure? OTP has excellent idiomatic tools for all that and more.

Elixir developers who need a queue generally reach for Rabbit (which any language can use), or something backed in a database like rihanna[1] or honeydew[2]. Rolling your own distributed system is very much a last resort, and despite its excellent concurrency characteristics the BEAM still lacks basics such as a battle-tested raft implementation. [1] https://github.com/samsondav/rihanna [2] https://github.com/koudelk…

> and despite its excellent concurrency characteristics the BEAM still lacks basics such as a battle-tested raft implementation.

A couple of years ago the RabbitMQ team has published a raft library[1] which they use in their implementation of persistent queues. It has a flexible API and implementing your own state machines is quite straightforward, as it follows the OTP gen_* behaviour paradigm.

And by now, I'd say it's pretty well battle-tested.

[1] https://github.com/rabbitmq/ra

Re: Lovely Week with Elixir

#138
post #137

Earlier quoted context omitted.

Elixir developers who need a queue generally reach for Rabbit (which any language can use), or something backed in a database like rihanna[1] or honeydew[2]. Rolling your own distributed system is very much a last resort, and despite its excellent concurrency characteristics the BEAM still lacks basics such as a battle-tested raft implementation. [1] https://github.com/samsondav/rihanna [2] https://github.com/koudelk…

> and despite its excellent concurrency characteristics the BEAM still lacks basics such as a battle-tested raft implementation. A couple of years ago the RabbitMQ team has published a raft library[1] which they use in their implementation of persistent queues. It has a flexible API and implementing your own state machines is quite straightforward, as it follows the OTP gen_* behaviour paradigm. And by now, I'd say i…

I didn’t know about that - thank you for pointing me at it!

Re: Lovely Week with Elixir

#139

Earlier quoted context omitted.

> Open to being told I missed something, though. The Bean keep using CPU even with no work to be done, so avoid context changes. We can't compare about CPU values.

We can't compare about CPU values Can you explain more why we can't compare? Looking at this chart... https://stressgrid.com/blog/benchmarking_go_vs_node_vs_elixi... ...shows pretty clearly how the CPU utilization grows linearly (ignoring some sawtooth) as the load increases, plateaus once the load remains constant, and then comes down linearly as the load decreases on the other end. Looks like a very clear mapping b…

It is explained in the blog post after that benchmark - https://stressgrid.com/blog/beam_cpu_usage/ .

Essentially in order to optimise responsiveness the BEAM uses busy waiting, which in reality is not actually utilising the CPU as much as is reported by the OS, which results in misleading CPU usage being reported by the operating system.

Post reply on HN