Sascha Wolf (00:01.124)
Hey everyone, welcome to another episode of Elixir Mix. This week on the panel we have Alan Weimar.
Sascha Wolf (00:07.852)
And Adi Ayingar. And me, Sascha Wolff. And we have no special guest this week, but we have an Adi, which has great ideas about topics. So Adi, what are we going to talk about?
Yes, I was thinking that there isn't really a podcast episode or a blog post that people can go to that acts as like a starter kit, right? If you want to deploy a production-ready Phoenix application, like, but here are the tools and frameworks you can look at, which are feasible for, you know,
V1 of the application without overengineering, right? And what use cases you can use them for. And we can go all the way from, you know, Elixir Phoenix Ecto to, you know, maybe how to deploy and even observe the application. So, yeah, starter kit if you want to deploy a production-ready Elixir application, a Phoenix application.
That's an amazing name he came up with. I wonder where he got the name from. Starter Kit.
Yeah, I just came up with it myself.
I'm just kidding, Alan suggested that before we started recording.
Sascha Wolf (01:19.445)
I don't remember that. It was definitely you, Adi.
you in the Kronkon house.
Sascha Wolf (01:27.588)
So yeah, what is in your starter kit, Alan?
Wow, definitely open. It's definitely in my starter kit for sure. Like I don't do any background jobs without pulling that out, that toolkit. Of course, Phoenix is definitely in there if you want to call that. I mean, would you count Phoenix as something in your toolkit? Like are you going at the elixir language part or are you starting from Phoenix? Because most of the time you're gonna be starting from Phoenix, right?
Yeah, I think that's fair. I think it still goes that saying. I know a lot of people have tried to use other ways to deploy their web applications. And Elixir definitely goes a few next sort of it's a first application. Once you understand the basics, you can try out. I think Ash is still pretty good now. But I mean, if you're trying to go the plug route and cowboy route, it could get very messy.
Sascha Wolf (02:20.916)
I mean, you can. And I've built a production ready application with only plug, but that also had like only two endpoints or something like that. So.
Right. And again, if it's a first application, like learn the lesser things you have to learn, the easier it would be for you to climb up that ladder of knowledge.
Sascha Wolf (02:35.62)
Sascha Wolf (02:42.456)
So Phoenix for API building, Oban for background jobs. And unless anybody of you listeners is aware, Oban is basically the sidekick of Elixir land, I would say. So like the thing that makes background jobs work nicely. The big difference between Oban and Sidekick, for example, is the Sidekick is using Redis, Oban is using Postgres. And I feel in general, the Elixir ecosystem has kind of diverged on, not converged on Postgres as the default persistence solution.
Yeah, totally. I mean, I'm going to add a little bit to that too. I think just, I know we have a lot of beginners who listen. So, background job processing, anything that happens asynchronously from user request, user requests for something you want to return and then process something outside of that lifecycle, right? Outside of the control lifecycle, schedule a job to run separately. And really, if it's a first Elix application, just don't put any thought to it and use O-Ban.
Same, like Sasha said, you're probably already using Postgres, which we didn't really talk much about, but your Ecto Postgres, probably already using that. Just hook the same repo with O-Ban. You get free retries, free rate limiting, free horizontal scaling, too. You probably won't worry about that if you're writing a v1. But O-Ban can push your application through quite a lot of scale. And it's simple to adopt and use. It's really a win-win to use O-Ban. So yeah, 100% on O-Ban.
Sascha Wolf (04:10.244)
Yeah. And if you're wondering at this point, okay, but I mean, like doesn't Elixir have background processing, right? Like this task thing, not around. And yes, it is. The benefit of a library like Oban is, as Adi just said, you get retries and everything, right? Like you get the whole shebang of like, okay, I now want to schedule something for later, I don't want to think about like what happens if this crashes, right? Because if you use a task, you can do that. And that is sometimes also the right choice, but if you use a task, well,
it's gone. Boom, end of story. And sometimes that's okay. Like, depending on the specific use case, that's perfectly fine. But more often than not, especially when it comes to user actions, that's not okay. And then like reaching for something like Oben, especially as a first measure, is probably the simpler choice. Because you'd need to jump through less hoops to get some kind of certain guarantees. It just works, in quotes.
And not to mention like all that, what would you call that? Like the history, right? Because if you have, I mean, you have the database stuff backed, of course you can prune it out and whatever, but still you have some kind of history, you can see what happened. There's been so many times where I have to go back in time and see did this job actually run? Did this thing happen? Does it succeed? Did it fail? And I think it also captures that, the error, if there was an error that happened. So the only.
Sascha Wolf (05:14.616)
bad thing that took me just a moment to kind of figure out which was like how to actually log that in the logger because I don't know if it's things have changed or not but I know before it doesn't throw the error to log but it does capture it and put it into the database for error messages. Do you know if that's changed or not because I know the only way to catch her is with telemetry.
Yeah, that's what I was going to suggest. I think you can just create the handler. It's very easy to do that. I think Oband even has a default handler that can be turned on configuration now, which logs it to. But yeah, I think it makes it pretty easy to just capture telemetry events and do whatever operation you want with it.
And I know there's definitely talk about like having other client libraries. So like something with Golang, I think was something that was talked about. I'm not so sure if he started working on that, but this was a while ago. He was talking about expanding into other languages, which would be kind of interesting because as time goes on, usually do I start adding in other languages, but maybe we kind of go off on a tangent about Obin, but I think that's kind of shows you the power, right? Is that, you know, it's really, is a really fantastic background job kind of processing tool.
Sascha Wolf (06:47.52)
It gets out of the way. And I think sometimes that's like the nicest thing you can say about a library or framework that you don't really need to think about how to use it. It just works.
Yeah, and again, I have to mention the testing library as well. They've put a good amount of effort in making sure everything is testable. To its core, you can test retries, you can test whatever. You can test events that are emitted after a job is completed. You can test whether it's, again, PubSub allows you to test it whether it's hooked up to LiveView really well and stuff. Again, it's a complete library.
I highly recommend that.
Sascha Wolf (07:38.316)
I mean, what is Obann running on, Adi? What is usually like, what are you used together with Obann? You use then like an Ecto-rappel, right? I mean, you briefly mentioned it already. So Ecto is also the one of the things that, I mean, I feel kind of obvious in saying it. It seems like the, like I'm preaching to a choir, but yeah.
Yeah, totally. If you're building your first Phoenix app, again, don't try to do anything fancy. Try to get the experience of managing a production-ready app first before doing something fancy. Use Acto, use Postgres, use Phoenix like we talked about. Yeah. Yeah, I felt it went without saying, but I'm glad you still brought up Sasha.
Sascha Wolf (08:22.188)
Yeah, yeah, I mean, in general, I mean, I can just, this is not exactly the elixir, but I just can't state often enough how amazing a piece of technology Postgres is. But Postgres is just so nice to work with.
Great. And I think now, Oban also works really well with the whole, I think, PG bouncer and stuff. Doesn't rely on some of the advisory locks that it used to. So again, it can take you far. Like, at MAD Team, they're really pushing it to its limits, and it's holding out really well.
Sascha Wolf (09:02.232)
Okay, so now I have a thing to build some APIs or maybe some webpages, right, with Phoenix. And then, I mean, just plug it here, Phoenix live view, potentially is the thing you might also want to look into it in general. Phoenix components and everything. I kind of would subsume all of those under Phoenix. So if you start out and you want to build productionary application, honestly, just dive into the Phoenix guides and dig in. And then persistence, right? Ecto, we talked about Ecto, background jobs, OBen.
At that point you might just be done, depending on your application. That might just be it. Um, but what else is there?
Yeah, I think there are some very quick wins. It might not come to your mind right away, but since we added the term production ready, some of security and making sure your app cannot be crashed very easily by spamming a health check UI or something, the rate limiting. Those kind of things start becoming important with the way Phoenix is designed and the whole plug architecture.
There's already a few libraries out there that do this really well. It's like rate limiting. I would check out XHammer or PlugAttack. Both of them allow you to very simply add basic rate limiting. PlugAttack is even super simple. Just use this edge table, which is by default in memory elixir term storage or line term storage. It's ETS.
Yeah, you don't have to add anything external to your Elixir container. To that, you can literally add rate limiting. And you can rate limit by IP address. And I know Xhammer allows you to do a few more things, like add custom IP address, block IP address temporarily, and stuff like that. So yeah, if you want to make sure, as soon as a Deployer app, it's not spammed by bots, check these out. Because it happened to me multiple times.
Even when I was, you know, especially when I was looking at a startup, it's very easy to scrape subdomains of a domain. And there are bots that do that. And as soon as a 200 response comes in or a 403 comes in, anything but 404, they start spamming to find health check APIs and all that stuff. So the rate limiting is super important.
I couldn't tell you how many times I've seen people trying to get WP admin all the time. Or like, htaccess and all these other random files. env is a big one, right?
Sascha Wolf (11:43.293)
I always have to chuckle when I see those in the logs, like the application log, when you see like admin PHP, it's like, no, sorry, no.
Ha ha ha.
We should, you know, maybe, maybe I should consider to make like a, our library that auto returns, like random stuff, you know, either like, you know, haha, I know what you're trying to do or actually just give them fake data. You know, that could be interesting.
That's a very cool idea. Admin PHP endpoint that just shows a fake admin page that doesn't do anything. Just they can waste their time. That's a great idea.
Yeah, I wonder if you guys use any other tools like these, besides Splug Attack.
Sascha Wolf (12:34.768)
which you cannot do with Phoenix.js, right? So yeah, definitely check out Alpine. I'm sure there is a way we can change Phoenix to support that, but I have tried plenty. And I don't think Phoenix.js is a one-to-one replacement right now for Alpine.
Sascha Wolf (13:47.428)
And just to give an additional context, Alpine is something you might want to look into, especially when you use Phoenix Live View. I mean, not necessarily only then, but it's especially useful then.
Sascha Wolf (13:58.328)
At least from my experience. I mean, a funny little tidbit there, from my understanding, Alpine was developed from somebody in the PHP land, when they built something similar to Live View in PHP, and they kind of wanted to have some more front-end interactability, and that is where Alpine came from. So it is something that at least originates in this whole Live View bubble, let's say that.
Yeah, I guess it depends on which context. But I think Alpine is good either way. I think Alpine and Liveview can contradict each other depending on how you use it. And I think it can get very tricky when a button calls a Phoenix hook, right? And you want to do update and Alpine context with that, right? Stuff like that gets very tricky. But yeah, I mean.
I actually think Alpine would be best outside of the live view, like outside of the live view mount, especially if you're mounting live view into a controller page, which is how I tend to use live view, just simpler that way. Yeah. But anyway, yeah, I think there's many ways of using it.
Well, that's the best part about it is, yeah, you can always reach for that JS helper that they have now in Phoenix, or sorry, in Live View, right? Yeah, but Alpine's great for, what do you call that? No matter if it's a Live View or a Dead View, right? Which is really kind of nice. So if you have that menu bar that pops up on all the pages, it's nice to be able to have it written in once.
I guess another quick one coming from a security side, again, in production applications, those things become very important, is check out Sobelo. Covers a lot of HTML injection, in some cases also SQL injection, only in some cases. But obviously, dependencies, old dependencies, your headers.
Everything. So yeah, Sobelow is like a nice security. And they keep expanding. It's a very well-maintained library. So at CI level, you can catch a lot of vulnerabilities before deploying application to production. Again, if you're building a production or the application, it becomes very important.
Sascha Wolf (16:33.092)
Yeah, definitely. It also catches something like hard coded secrets in your configuration files, stuff like that. I mean, I literally had to work around that just today because I migrated some of our compile time configuration to the runtime configuration and the dev repo setup is just Postgres, local development, whatever. And then Sobheda was like, ah, you have some secrets here. And I was like, yes, Sobheda, that's fine. Please don't.
bother me about it. But in general it's a very useful tool. It catches things like those and especially when it comes to secrets, right? That is something you better be safe and sorry.
Well, another thing, I kind of want to expand upon this in another direction, right? I mean, we're talking about run time when your app is running, but what about when you're actually developing, right? I know Adi, you're a big tester. I mean, for sure, three things I like to bring in to my app is mocks for mocking out things with behaviors. Faker, because generating like fake data and it's nice to have random fake data because you can find some other weird issues with that.
And then the other one would be X-Machina, which just makes life so much easier where you can generate parameters, bring parameters, and of course, insert data into your, using factories into your database, super helpful. And all those combined together, really a nice toolkit, I think.
Yeah, totally agree on Faker and XMachina. I think both of them I use. I just have it in my template of my Phoenix project to always have them included. Mox, I go back and forth on. But I know it's more, I guess, depends on your opinion. But XMachina and Faker are pretty objectively best testing tools. Well, I guess a lot of people don't like XMachina either. People like to build their own.
factories and just use Faker, but I'm very much on the Ex Machina plus Faker team.
Sascha Wolf (18:36.184)
Yeah, especially if you have like a more active, like persistence heavy application, right? Like something that is very crud heavy, create, read, update, delete, then something like XMAC to quickly create test data in your database. It's just, it simplifies, it simplifies things.
And also to create data in your dev database. You can also use it in like dev environment, in the QA things locally.
What about, I'm also a big fan of, have you guys ever worked with something called Briefly before? Have you seen that before? Okay. What's really cool, so there's this package called Briefly. I think it came from...
Same guys who work on absinthe. It's basically a way to create a temporary file or temporary directory that gets cleaned up once the process ends. So whenever I have to generate files or handle something and I wanna clean it up, I always use Briefly. It's super nice, it creates it. I mean, you can obviously put it wherever you wanna put it, but default it puts into your temp folder.
And then once the process is done using it, it gets cleaned up immediately, which is super helpful if you're working with Kubernetes or something like that where you can't keep flooding up the drive with data.
Sascha Wolf (19:56.572)
Something I also want to plug in that kind of goes into the same direction as what you just mentioned with Sobelow, Adi, but I think Credo is never a bad choice. I'm personally very fond of the default settings. I know that people like to use Credo also for strict settings.
when it's more of a traditional linter. And just maybe to give you a little bit of a gist of what Credo is about, it's also a code linter. But there's a bit of a difference between Credo and some other code linter, unless you use the strict sentence, and then it really behaves like a traditional linter. And that Credo tries to figure out, well, how do you usually write your code? And then it nudges you on consistency. So just one example, maybe the ordering of your aliases and requires and imports and the...
And then it tries to figure out, okay, how do you usually order those in your code? And then when you diverge from that in one module, it will say, Hey, you're doing it differently over there and usually you do it like this. And personally, I find that very, very neat. Um, yeah, since we like, and then we are in the application we're building at work, we have it set to strict because that's like more of this opinionated thing. And like, it's better for like keeping the same consistent code style. But if it's your application, you mostly work on that.
Credo without strict settings is still very useful. And it kind of also nudges you to what some best practices. It doesn't only look for consistency things, but it also looks for some, has some best practice checks and so on and so forth. And so if you are starting out with Elixir, maybe don't have that much experience and kind of want to get to a production ready thing, then Credo is something that can also help to learn along the way.
Yeah, plus one. Yeah, I think one of the things about Credo is also that on top of the tool, it also provides a framework to extend it. Very easy to add your own checks. And just instead of adding a separate CI check for a different thing, just keep expanding on Credo as long as it's compile time. So yeah, huge, huge fan of that too.
in my current team, we have like at least seven or eight custom critter checks for different, it doesn't have to be like, you know, the code, kind of like the standardization of code. But also if you're doing something weird, like one of my current work, I'm like doing something really weird with O-Ban. And it led to the, you know, to a point where we cannot call O-Ban.insert. We have to go through a separate library, right? And like policing patterns within.
your how something is used. And again, it's a compile time check, right? It took like 15 minutes to write a Credo check to add stuff like that. So yeah, it also provides documentation, right? And also a nice like a compile time check as well. Huge fan of that. Also, isn't it called Credo? I think you were the one who, well actually you were the one who mentioned, you said, you know the creator and you said it's Credo.
Sascha Wolf (22:36.432)
Sascha Wolf (22:51.369)
Yeah, probably. You're probably right.
Sascha Wolf (22:57.368)
Yeah, probably true. Maybe, maybe I got infected by someone of you.
Sascha Wolf (23:05.876)
And when it comes to testing, I just want to jump back to like one testing thing. If you are not a fan of mocks and maybe you want a more traditional mocking experience because mocks is kind of assuming that you have behaviors and then it generates test mocks for those behaviors, there's a library called Mimic. Which kind of has like a very similar API surface to mocks, but it really allows you to say, okay, I want to mock out existing modules. It is a bit hit and miss, especially when it comes to macros, because then
funny shit is starting to happen, honestly, if you want to mock out a module that also has some macros. But a part of that, it works fairly well. And in our code base, we actually use both. We have parts where we use mocks, and that is the default choice in general. But when we want to call into external dependencies, yeah, you could then wrap that again in a module of your own, write a behavior.
But then it's honestly just simpler to say, okay, now I'm going to use Mimic to check that I'm calling this particular dependency correctly over there. So yeah, I'm, I mean, tend to use both. For me personally, I'm more of a Mox fan, but Mimic is a nice tool to have.
I guess one thing that people might, and this is branching off of testing a little bit. Another thing you might start needing maybe quickly, I don't know, it depends, is a little bit of caching. Especially if you're using Postgres quite heavily and some of the queries are very heavy. Something like NetBillX could be super useful. It works best with Redis and it does that, but it also works with like.
local, your term storage. And it can also be distributed if you do decide to scale your application across multiple nodes. But yeah, I think I would check out Nebulix as well for caching. If you're making multiple queries multiple times for data, that doesn't change that often. That's a good use case of that.
Sascha Wolf (25:20.804)
Alternatively, the library I also like to reach for is a cache X, because Nebulex kind of comes with some... Is it more of an opinionated caching library, which is perfectly fine? Yeah, yeah, definitely. But I mean, it also comes with this option to use the decorator pattern that will annotate the functions you want to get cached. And in some cases, that is honestly really nice, because then you can just... The business logic stays the same and you just...
It is. I think it's also bigger. It's got more features too.
Sascha Wolf (25:47.728)
plug that thing there and say, okay, this things would be cached for like five minutes and a story. Um, but sometimes if you, uh, a bit more lower level, I guess, or more, how should I put this, but more, um, uh, less bells and whistles, but also more flexible in that manner, I guess is, um, cache X and like when I just want to quick and dirty caching and without really thinking about it, then I usually reach for something like cache X over and every legs, but that is my personal experience.
Interesting. I've actually, interesting. I feel like I'm kind of like a little opposite. If I want something quick and dirty, I would go with Nebilix. And if I want to fine tune my caching, cache gives me more control. I think what I like about Nebilix is it literally take you less than 15 minutes to add it, add caching with decorators, and also add test for it. It just have everything built in. And I think it also supports cache six as a.
engine for caching. So I think you can also turn Nebulix off if you want to find your caching with cachex. But yeah, it's interesting that you use cachex for quick and dirty. I feel like Nebulix
Sascha Wolf (26:59.853)
You... I... When I say quick and dirty, I really mean it in the sense of... Okay, I'm just...
writing some code over here and I want to have it caching for now, but I'm not maybe not quite sure on the API it will have in the long run, right? Then, then just plugging some cache, cache X instructions here and there, like maybe having a wrapper around like one particular part of the code tends to be easier. And then for example, when I actually come to a point where I say, okay, now I kind of settled on the API. I want to have this on the module high level API, then having something like
Sascha Wolf (27:32.604)
Usually the straight, most straightforward solution. I mean, literally today I kind of battled against Nebulex because I wanted to, um, I wanted to put some default configuration inside of my cache. I wanted to say, Hey, please use this telemetry prefix. And it turns out there's no really easy way to do that. Like you can put it in the configuration file. You can put it in the supervisor, but you can't easily put it in the module which defines the cache and I found that super annoying.
Sascha Wolf (28:03.304)
And I mean, like something you... Sorry?
What about Timex? Sorry, Timex is a huge one. Probably nobody mentioned that one.
Sascha Wolf (28:08.036)
I actually, I, I want to maybe save that fault, Alan, because I'm like something you also probably want to cache very often is API integrations, right? Like when you call into a third party thing and the tool I'm usually using there is Tesla, especially when I'm building, like when I know that I'm going to integrate into Equifax, particular API over there, and maybe there, maybe there's a library for it. Then yeah, I'm going to use that. But if there isn't.
Sascha Wolf (28:34.244)
And I'm going to use Tesla. And with Tesla, you can build out your module where you say, okay, like it has this top level functions that kind of represent actions on that API. And now I'm using it to like build that request and send it and also build in testing. So you can, in Tesla, just mock things away super easily. But it really allows you to say, okay, I want to have that particular, yeah, that particular.
integration with that particular API. And I want to have a representation of it in my code base as a module and using Tesla for that. And Tesla itself comes with some, I think by default it uses Hackney. I'm not sure entirely sure which HTTP client it uses, but you can also plug in whatever. You can plug in Finch, you can plug in all the other HTTP clients. And that is more of an implementation detail, but the API to kind of...
specify what kind of HTTP integration, like what kind of headers and so on and so forth. If you want to add all of that happens through Testa. So far I've found it a joy every single time.
Yeah, I like Tesla a lot. I think one of the, yeah, I think, like you said, it's very heavy, heavyweight, allows you to do so many things. And again, simple, if you want to just use it very quickly too. Interestingly, they said you use it for external API caching. I would use Nibblex for that too. I would just cache the interface.
Sascha Wolf (29:53.384)
No, no, I meant to say, I meant, yeah, exactly. I meant to say like, uh, something you also want to cash usually is like an integration with an external API. And for that, I usually use Tesla. And yeah, and that isn't a nice thing there, right? Like then you can easily say, for example, you're going to specify your Tesla client for an API and then you slap some nebulas on it and done.
Gotcha, gotcha, gotcha. Okay, okay, okay. I see, I see, I see, okay, okay.
Right. Right, exactly. Or just the decorator in the function itself. Yeah, yep.
Sascha Wolf (30:17.477)
Alan, you had a pretty awesome library that you were mentioning.
Yeah, sorry. Timex is a huge one. I mean, like whenever I want to do anything with time zones, because most of my clients are not in the same time zone as me. So I have to do this a lot. Even if they're in the same time zone as me, like my financial one, they want to do, I don't know, I forgot what the reason why, but they always want to have their system in Cape Town time, so South Africa.
It's a little bit weird, you know, they're based here. Somehow they find that Cape Town just makes life easier. I think it's the way they trade certain markets. It just makes more sense. So it's, it's interesting, like, um, how easy and how useful that one is. Of course, most of the things built on like TZ data, things like that. But, um, I mean, of course things now in Elixir Standard Library is better, but when it first came out, like we didn't have very good support for dating times and time zones and all this kind of stuff, but.
I think nowadays you probably can get away with things, but still the convenience methods within Timex, I think are just worth it just to bring it in.
I agree. It's, again, one of the things that's in my default template. And even if you're not playing with time zones, formatting, calculating difference, and any kind of operation, time-related or date-related operation, calendar-related operation, TimeX is just like convenience as a word. It just has functions for everything. Yeah.
Sascha Wolf (31:44.304)
I do want to pluck it. If you don't need to do elaborate time operations like conversions, compare between time zones, but maybe the only use case you have is something I want to be able to parse different timestamps in different time zones, and that should work out of the box. Then at this point, the Elixir Standard Library is actually really...
really there. The only thing you definitely want to do then is download a library called tz underscore data, I think. And then you can plug that in as the time zone database for the standard library. And at that point, the standard library becomes able to also parse timestamps in different time zones with different annotations and gives you then the date time structs. That is something we're using inside of our application, because we don't need to do any.
calculations, but no shifting, no comparison. We do have the need of saying, okay, we want to be able to parse certain timestamps and to kind of retain what kind of time zone were they in. And at that point, you don't need to reach for something like Timex, which you still can do. I mean, like if that is the mojo, go ahead. But I wanted to pluck that it's no longer a necessity. Like a few years back, actually, the standard library was not quite there, but at this point, it is.
you can do that. And if it retains on a simple level where maybe you want to convert between two time zones or maybe you want to add a few seconds or a few days to some time and shift it, that's also very much possible inside of a standard library. But as soon as it gets more complex, then better use Timex because you can do it in a standard library, but Timex makes it convenient.
I just haven't yet to write a production application without Timex. I think just formatting, yeah, one line function. I think one thing especially that I feel like very quickly, if you have more number of users per second, like D2C kind of an app that you're building, not a B2B app, you might need a go, seconds ago, all those things, right? Like those little helpers to add...
Sascha Wolf (33:54.733)
Yeah, that is also user interface. Then, because I mean, like in our case, we're building an API. I mean, like we have an AppMan interface, right? But maybe we'll actually use Timex there. But right now we are building an API and we need to power user data, like user given timestamps and that kind of stuff, but we don't need to do much formatting with it.
Ah, there you go.
I mean, is there any API specific stuff that you use when you're building on your APIs? Because like, for instance, we just built out like a REST API. We're using Swagger finally. We have this open API generator that we're using to make life easier.
Sascha Wolf (34:29.54)
I mean, this...
Sascha Wolf (34:41.772)
One thing I usually always plug in because it's not a big effort is there's an eTag plug. And I'm not sure if you're familiar with eTags folks, but eTags is one of the mechanisms for which caching can happen through HTTP. The idea is kind of that on the response, you include this eTag header, it's really called like that, and it has some value and then clients can take that value and send it back to the backend and say, okay.
If this matches here, then just tell me. And then like the flow there is that it sends a free or for not modified. Or I'm not sure entirely sure what the exact HTTP status description is, but it sends a response that says here, I don't give you any data. I'm just going to tell you that the data you have that is specified by that e-tech is up to date. Um, and that is, there's a plug and hacks. It's actually written by me because we had a few years back.
application, wanted to do that. And then I kind of extracted that into a library and I haven't really touched it since then because it just works and you can just plop it in your pipeline, put it there, forget about it. And it's especially nice when you have some mobile clients, maybe with like a not so great internet connection because you it's free bandwidth saving. If the app, for example, does have some caching built in and can then say, Hey backend, please give me that resource by the way, here's the e-tech. Then the backend can say, yeah.
You got it, it's up to date and you save some bandwidth. And it's one of those fire and forget things.
I think there might be another one that someone wrote a while ago. I think it might be Mihael? Mihael Muskawe? Yeah.
Sascha Wolf (36:19.736)
Yeah, there's basically a difference between it. There's two ways to go about eTags. There is, now I'm going to go into nerd mode, but there is the shallow eTag, that's the eTag plug. And the shallow eTag, what that means is it's not aware of any content. What this thing does under the hood, it takes the response body, it makes a hash out of that, and that's the eTag. Then there is deep eTags. And for deep eTags, that means you have context awareness. And that of course also means more code, right?
So for example, you might be able to say, hey, I kind of compute an ETAC or something when I insert a thing into the database, right? And then I kind of put it in the database. And then when a request comes, I can kind of maybe check that field. Hey, they are asking for a resource with this ETAC. Does that match? And then you can maybe even save some computation. And sometimes that makes sense because then you also save compute time on the
Sascha Wolf (37:16.076)
It's context aware, so you need more effort. And the library that Michal wrote actually is like for deep e-text, that's the whole thing. And the library I wrote and haven't really touched on it yet because it just works is shallow e-text. So it was just charm because you really just plop it in your pipeline, forget about it. It has nothing else you need to do. And especially when you have mobile apps, those tend to be happy about the safe bet.
Awesome, so we talked about CI, we talked about kind of like dependencies based on use cases. I guess like one thing we kind of touched last time too is like, you know, observability and kind of logging and stuff and my go-to for that is AppSignal. Just because of convenience again, it has great integration with Elixir and Erlang. It gives you...
A lot of observer insights, like, oh, memory usage of a process, overlying process, and stuff like that. And it's free to use, I think, at least for first month. And it's very inexpensive. I think it's like $5 a month or something, and which is not a huge price to pay for a production application. Yeah, what about you guys? Do you guys have any experience with App Signal? I know one more thing I'm a huge fan of App Signal is that just the ability to.
send and analyze any data simply. I know Datadoc can do the too, obviously, but it's just so complex. Learning Datadoc itself is similar of effort as learning Phoenix in a way. An app signal, you don't even have to learn. It's very intuitive, simple, and you can use it for your app observability, instrumentation, and analytics.
actually analyzing the performance of a product. You can start sending user insights and use AppSignal as a number of sales, conversion percentage, and stuff like that, which I have done before. And it's pretty useful to have one $5 tool that does it for you.
Sascha Wolf (39:33.4)
I don't really, I mean, I personally have mostly used, my experience kind of has been with Datadoc or self-built monitoring for like the log aggregation stacks, those kinds of things. I haven't really done any app signal yet. So I personally, I probably would give it a spin. I would also probably, I mean, like at this point, maybe, maybe that, I mean, like this leaves a little bit of the production ready.
backpack like you want to start with and kind of goes into the okay, like where do you want to expand into something? That's like the extension or no what I'm going to start with weight Is what I usually then what I would do now that would build like an app from scratch production ready I would opt into telemetry from the get-go for like Emitting traces and events then kind of Transform then into open telemetry that have an handler that kind of puts them into the open telemetry stack and then have a collector
which pushes them, for example, into AppSignal or into DataDoc or into Honeycomb, because that is what I would do now personally. I would have that set up with the collector and then try out some, a few different solutions. So I would actually try out, hey, how do I like AppSignal? Hey, how do I like Honeycomb? Hey, how do I like LightStep? Right, and can I make an overview of what kind of those different solutions I would like? So this may be leaving a little bit of the, I just wanna get rolling quickly, the end, this is my startup pack for building a thing.
But what definitely is interesting for the starter pack is telemetry and open telemetry. And then you can export those to AppSignal because you don't have that vendor login. If you use the libraries that are available for those software as a service, observability providers, and with open telemetry, as the name kind of suggests, it's...
an open standard and you can then export those to AppSignal and get still all Datadog or whatever, right? And still have all of the niceties of observing applications without the disadvantage of being kind of hardly bound to one specific provider.
I guess I was coming from, you don't want to spend more than 10 minutes on starting to observe your application, right? Like a very, very basic starter kit. Just add something to your hex PM, add an environment variable, boom, start observing in an app signal. But yeah, I think just definitely avoiding vendor lock is, I mean, based on the kind of project building, you should definitely evaluate that, right? Like how important is it? And I think, I guess like
my next one was going to be deployment. I think same goes for deployment. My go-to solution is Heroku, and actually also taking Fly lately. But yeah, no matter what solution I go to, I go through the container approach to add at least some kind of flexibility. Obviously, there will be a little bit of customization based on Heroku and Fly. But as long as you go to container route,
most platforms will make it easy for you to deploy containers. But yeah, I would definitely check out Heroku and Fly. Fly is free if your monthly bill is less than $9, $9 or less. So that's an advantage of Fly. And the only thing that sucks about it is it doesn't have a lot of support. You cannot quickly add Redis or expand your instances very quickly. If you want to increase a proposed quest data and stuff like that.
It doesn't have very good integration with, like if you hook up your Heroku with AppSignal or Datadog, within seconds, you'll have Heroku level insights as well. But Fly doesn't have anything like that. But yeah, it's run by a lot of significant Phoenix people. So it might be worth giving it a try.
I don't know, I've heard a lot of good things about Fly, but I haven't had the best experience. I don't know, I've had really bad experience, like where the database went down for some reason and it didn't get rebooted. And apparently they said this is not normal. So maybe, and you know, I've ever complained about some other things I've had with them. And yeah, I was just kind of surprised because like you said, everybody, and you said not everybody, but quite a few famous, or
More well-known people in the luxury community are using it or work in there But I'm just like a little bit surprised about I mean you mentioned about the support, right? For me this support is really not there. Like I mean like and when I have an issue I cannot really contact them. It takes a while to get back to me It's that part is not the best but I mean Yeah, and today you're a CI went down because like we couldn't grab like
Yeah, I would agree.
So they have containers where you can use the fly CTO, but for some weird reason, it doesn't work in GitLab, which is what we're running our stuff on. And then I tried to ask for support about like, how come I can't use this? And they just say, well, you're not using it as intended. It closed the issue. So the only way around it I found is like installing it through like a curl command, which they talk about. That's been working, but then sometimes it stops working where like, I don't know what happens with their infrastructure, but I'm unable to download that, the installer anymore. Like today, it's just not working. Yeah.
That's the exact problem that I ran into. Their GitHub action doesn't work always. And the flyctltool isn't always available to download. So I just curl it and cache it. That's what I do, which is silly. But I think the only reason why I also deploy my side projects to, I deployed to Heroku and Flyboard that I.
I don't load bands across them. I just have fly one that I use on my own and use a central database for both of them that lives on Heroku. The only reason why I have it is because I want to be up to date with where it's going, because a lot of big Phoenix and Elixir players are invested in it. Invested as in like, at least like, have invested their time at the very least in it. So yeah, but Alan, you're right.
it's not at a place where if someone doesn't want to learn it, if someone doesn't want to deal with extra pain of coming up with CICD tasks for Fly and dealing with what they had like 4% downtime, right, this past half year, which is huge for a cloud provider, right, 4% downtime and like active, what is it called, you know,
heavy, heavily active time, whatever. That's huge. We're Heroku and AWS and all these things. We're talking 0.01, right? So yeah, we'll definitely check out Heroku. It's not free anymore. And they have like ECO dinos, which are supposed to be environment friendly and also don't always run, which kind of costs you like $4 a month or something. It's not free, but $4 a month for that, and maybe $5 a month for postgres, like $10 a month.
If you can afford that, I would definitely go that route. If you want to go to free route fly iOS free right now if your bill is less than 10 bucks a month.
Where'd you get the stat for the 4%? I would love to see the...
I was reading an article. I can try to find the link to that. But yeah, I think it's high volume downtime. During the time when the volume is high, the downtime is 4%. Whereas here, it's across the board is 0.01, pretty much 0. So.
Actually, you know what? Maybe if I can find the article, maybe let's edit that out, because I don't want to, it's fly, and it's some elixir, folks. So maybe we can just edit it out, the 4%, especially if I can find the article. I don't want to get in trouble.
I don't think it's any trouble. I mean, if anybody has any information about this, I'm curious to know because I haven't had the best time and I would like to get some more information and I hope that they can get better because I do have high hopes for them. That's why we actually pushed our client to use it and then sometimes we don't feel very good about that, but I mean, we're still kind of, we're still using it, right? We haven't left. So we're hoping that it does improve.
Yeah, sorry, I'm going to ask them to edit out. I'm not comfortable. Even if it's true, I'm not comfortable saying this. Sorry.
Sascha Wolf (48:31.184)
Where do we pick up again? So we honestly, like, I'm not sure. So we had the whole Heroku fly.
I can conclude that maybe just and then we can go to. But yes, I mean, Alan and I agree. I've had some tough time with Fly too. But I know a lot of Fly is still a work in progress. So if people want to have more consistent, easier to manage cloud providers, cloud provider go to Heroku, I think their dinos, eco dinos are like $4, $5 a month.
Sascha Wolf (48:43.105)
Postgres is five bucks a month. And they give you a lot of discounts as well. If you consistently use it, every now and then I get like 20%, 30% discount. Heroku, they just chop off a little bit of my bill. But yeah, Fly.io is free. But if you can afford 10, 15 bucks a month for a production application, check out Heroku.
Sascha Wolf (49:32.936)
And something we haven't really gone into yet is, I mean, the whole application we are kind of envisioning right now, right? It's this more traditional CRUD application than, okay, we have a monitoring, we have integration with two external APIs, we have some caching, we have testing. I mean, these day and age, you might also want to consume and ingest a whole bunch of events or in general event-like resources, data. And at that point, you probably want to reach for something like Broadway.
because Broadway is the library that makes ingesting these sources, like Kafka or anything honestly, relatively straightforward. It's not super straightforward because honestly, the whole topic in itself is not super straightforward. And you kind of have to think, how do I want to ingest those? How do I want to route those? Can they be ingested in parallel? And so on and so forth. Is order relevant?
All of those are questions you will have to ask yourself, and that entirely depends on the specificities of the application you're building. And sometimes out of order events are perfectly fine, sometimes they are not. But something you probably don't want to do it is build that stuff yourself. And then Broadway kind of enters the picture and makes consuming those kind of event data relatively straightforward.
Yeah, I agree. I think another way of minimizing or at least delaying having to do something like the event consumption or at least throttling event consumption, like Broadway, is just, again, redesign workflow around O-Ban. It can really provide you that lot of throttling, batching, and asynchronous capabilities, which, again, you have to be a little smart.
By smart, I mean like cheeky or like come up with ways around using that. But if you're deploying your first production application, I would not even recommend you going and doing anything event-driven at all for the first few months.
Sascha Wolf (51:41.112)
I agree. It might just be that for particular context, for particular app you're building, you are kind of already like a downstream of something that is event driven, right? That is entirely possible. It depends on the context. And in that case, something like Broadway can save you a lot of hassle. So I wanted to plug it here.
Yeah. I think speaking of Broadway, a lot of Dashbit libraries are just like add like a one single plug, right? Like I mean, there's Nimble CSV, Nimble Options, all of these are check out Dashbit's GitHub. They have really small utility libraries, which a lot of them don't even have external dependencies, which make it really cheap to maintain and bring them in. So yeah.
Nimble CSV and nimble options is something I use a lot when I don't want to use ecto to validate options, right? Because that's the best way to do that, but it's very heavyweight. Nimble options makes it very easy and obviously nimble CSV, if you play around with CSV, any kind of importing exporting as well actually nimble CSV is pretty useful.
Yeah, Nimbus. I basically all these Nimbus, the Nimbus series are really good.
They even have Nimble OTP, which is quite interesting. I used that quite a few times generating OTP, you know, one-time passwords. It works with Google Authenticator, super nice.
Sascha Wolf (53:01.073)
I was very confused for a second because I was like, wait, they have like some wrapper around like OTP, right? Like what kind of what kind of things do they do? Is that like some process? Right. And then, oh, OK, one time password. OK, I got it now.
Oh, sorry. It's T, it's, yeah. Sorry, it's, I think it's called Nimble T-OTP for time, one-time passwords, you know, time-based ones.
Sascha Wolf (53:18.44)
Okay. Yeah, but especially NimbleOptions is something I've fallen in love with recently. Honestly, that is one of the boilerplate things I've been most annoyed with, with writing. Like, okay, I want to have some options here and I want to kind of make sure that maybe people pass on the right stuff. And then NimbleOptions is just so nice to use. And it also helps you generate documentation. It also helps you generate type specs. And all of this is something you can do with NimbleOptions.
While it's not super critical if this is an app you are just building for yourself, it's also not much of an overhead and you do catch errors through this. Right? Like you can basically ignore a whole category of, of maybe test cases, right? Where you say, okay, I want to make, I want to have some tests where verify what happens when I pass some other data into my options. And if you have something like nimble options, well, that thing does it for you. So yeah, really cool.
I guess one last utility one. We mentioned it last episode too, but Benchy. Again, quick shout out to that. Very easy to do benchmarks for any Elixir function. And also, it's actually pretty good too. It gives you an entire standard deviation of the entire distribution of the function, depending on how many times you run, the more accurate it gets. So that's pretty cool too.
Um, yeah. And again, if you want to do any kind of observability or whatever, check out our previous episode, we talked about that in depth. Um, there is one thing I want to talk about cause Alan mentioned absent. And, um, I want to talk about that too. Um, now in my experience, I feel like a graph QL interface. If you read or write a query or mutation, I think just gets very hard.
to maintain very quickly. Especially, I think, authorization. With nested schemas and stuff, I think it just gets very tricky if you're exposing a GraphQL interface directly to a user. But if you're exposing it to a separate application which further consumes it, wraps around the authorization layer, Absinthe, I think, is an overkill. And I've had a great experience using something like Hasura, which is just a
GraphQL wrapper around your database. And it has, you can add authorization and stuff to it as well, rate limiting, all that. And it also has a, like a web socket server. So you can, subscriptions and stuff work really well, like real time updates. You can get like real time updates without even live view or any kind of publishing, infrastructure for publishing. You just need a subscriber. So yeah.
Hasra is a huge college elixir, but I have built a lot of startup early stage applications and added Hasra to it just to add the graph QL. You know, layer with ease with like almost zero maintenance.
Yeah, I heard about this. Isn't there another tool that has something similar? Where you can build like that there's is that the one that hooks directly into Postgres, right? Okay, maybe it is this one. Yeah, I know a lot of people who like, who use this as kind of like their bread and butter whenever they're making something, they just kind of do all the work in there.
Not that I'm aware of but...
Right, and cool thing is even if you don't want to use GraphQL, you can wrap up a GraphQL query into a REST endpoint using Hasura's admin interface. Great use case for this is if you're building, and this is something I used in my previous startup, I had a technically aligned person. I taught that person how to use GraphQL, or Hasura's admin interface, and just gave them the read replica access.
Even if they try, they cannot write. And boom, read whatever you want. The reader replica on a stream replication, it would not have any sensor of data that would get over the end of the world for the company. But you can expose it to whatever, expose it to a paper form, and add a form submission software. Just completely, it just completely makes your ability to do experiments easier. Because the question is, what is the best way
Sascha Wolf (57:45.409)
It's a very good no-code solution, which, again, talks to the rest of the application because it gets real-time updates.
Sascha Wolf (58:05.096)
How do you then, do you use any particular tooling to create write those GraphQL queries? Or do you just have them as strings in the application?
Yeah, I mean, to start with, you can have it in the most strings, but like I said, you can wrap GraphQL queries as REST queries within Hasara. So just make a REST call, a GET request that gets you data.
Sascha Wolf (58:23.944)
Okay, but I mean, because I was interested in like, again, like startup pack, right? Like is there any dev tooling you're aware of, like if I have building a GraphQL client in Elixir? Because I also did that for work recently. And I used like GraphQL, like interactive editors in the browser to build the query and then literally copy pasted it. And...
I don't think there is a very good GraphQL client at all. Not even, not just at Elixir, right? I think as long as you use the schema introspection, the schema.graphql to validate what they're doing, how you come up with it, you know, I think it's like depends on your use case. Like that's the only qualifier for me for a GraphQL client side to be good is to make sure your queries are validator.
Sascha Wolf (58:49.41)
Sascha Wolf (58:56.656)
at compile time, right? Because you can get schema.graphql of a module without running it. Just run it once, boom, get schema.graphql. Use a GitHub to get it to a client. And before even deploying, make sure your schemas and your queries are somewhat valid.
Sascha Wolf (59:32.236)
Okay, but this is code you've write yourself then? Or I mean, what does the verification there?
Yeah, so I can pitch my Elixir package that I wrote a while ago. That does compile time or runtime schema introspection and introspects a query without actually making the call. I actually forgot the name of it. I think it's called Common GraphQL Client. And I can put a link to that. And yeah, there is. I can put a link in the show notes. It's actually pretty.
pretty cool. But it just uses Apollo in the background and changes configuration and environment variables to make sure your queries are valid. Where is it? Client query validation there is.
Sascha Wolf (01:00:24.752)
And then maybe this is like also a wish at the Elixir community at large, because it would be really nice to have something similar to Heats, I don't even know how to pronounce that. So like the HTML aware Elixir template thing, right? I happen to have something like that for GraphQL queries. And the very first step at this point, I would already be happy if it would just do syntax checking, right? Like there would already be a boom where I can say, hey, is this even a valid GraphQL query like from a syntax level?
Sascha Wolf (01:00:54.806)
go ahead and say okay now maybe have some additional logic to say okay now I want to verify this already valid query against some schema and that would be really nice like an if I can do that for example in the CI right in the CI step that would be amazing.
That's the exact purpose of this to do it at CI. Before you even deploy your application, make sure your queries are valid based on expected schema.graphql.
Sascha Wolf (01:01:18.388)
Yeah, because I mean, that is the thing. I think GraphQL is something that people sometimes reach too quickly for, I feel. Because you do lose a whole slew of useful HTTP stuff like caching that becomes a whole slew more difficult. But when you are on the client side, on the consumer side, and you have a product, I mean, for example, like a CMS that has a GraphQL interface or Hasura, as you mentioned.
then having a little bit of those tooling to make you sure that you don't have a typo in there somewhere, then that's super useful.
100%, yeah, the biggest use case for GraphQL is this contract, which almost zero effort, yep.
Sascha Wolf (01:01:57.836)
Yeah, the contract exactly. Yeah.
Sascha Wolf (01:02:07.528)
Okay, I'm looking, I kind of kept a list while we were talking. And I mean, honestly, we are kind of pretty well covered. I mean, we talked about Phoenix, we talked about persistence, we talked about rate limiting and how to build front ends of tailwind. We talked about security and maybe like a super small plug here on the security side and you already mentioned Sobelow. If you build something that has maybe a bit higher profile or you really want to make sure that it's safe, that it's secure.
then maybe reach for a product like Paraxil IO. I mean, we had the person that founded it on the show and it's an Elixir specific solution and it helps you keep your product safe. And we have an episode on that, maybe check it also out. He's talking a whole bunch about also like how they kind of do bot detection, right? And all those kinds of things. So if you think that would be a concern on your side, then like a software as a service solution such as Paraxil IO might be worth your while.
We talked about testing, we talked about mocking, caching, how to build HTTP interfaces, about time, we talked about observability in the sense of libraries, but also service providers, about hosting and deployments, we talked about eventing, we talked about dev experience with all the Nimble libraries. I feel we got it covered. I mean, if anybody actually listens to this in the sense of, hey, I haven't really built anything production ready yet, and now I want to, I feel
very thorough list and a very long list of things you might want to check out.
For sure, yeah. I do want to add, and I think it's been a while since I've said it, but I hope that people, I hope there isn't a need to always remind people, if people have questions, just reach out, at least to me. And I know Sasha and Alan are also happy to answer questions. So just feel free to reach out about any of this. Yeah, more than happy to help.
Sascha Wolf (01:03:59.344)
Yeah, yeah, definitely 100%. And you also, you don't swamp us. I haven't really gotten a DM yet. Ha ha ha. Nope. I'll telegram you, I'll telegram ahead.
Yeah, I had a bot actually reach out to me. No, on Telegram, some bot reached out to me, asked me how to process data in Elixir. And I was like, who are you? And they replied, I'm from Germany.
A single one?
Sascha Wolf (01:04:18.246)
And I said, but who are you? You got the same one? Yeah, yeah, okay. So it looks like somebody's listening.
Sascha Wolf (01:04:23.096)
I think I got the same bot message. Yeah, I asked apologies, and then they asked back what, and I was like, OK, block. Ha ha ha.
Wow. OK, this is crazy. I get an email roughly every other week through the podcast. So yeah, maybe you guys should be more open. Hey, you can reach out to us too. I'm kidding.
Was it Amber?
Sascha Wolf (01:04:44.304)
Sascha Wolf (01:04:48.668)
Sascha Wolf (01:04:52.904)
You can immediately, I'm gonna plug my email address now because my email is dev at saschawolf.me. So this is where you can reach me. Yeah, now you can reach me. And I'm also on Twitter, but honestly I'm not really monitoring Twitter since the whole Elon Musk thing. Like Twitter kind of... I'm also on... I don't know how to pronounce it. Hachiderm.io, it's mastered on Instance. I'm also there on Wolf4Earth. Better I monitor more actively.
Sascha Wolf (01:05:22.688)
But yeah, you can reach me through email. I don't know, you want to pluck your email too?
If you want to reach me, just look up for Adi. Send it to Adi and ask Adi to forward it over. No, I just want to annoy you, basically. Double the spam. No, I mean, I'm sure if people want to get ahold of me, no, but I mean for real, I think if people want to get ahold of me, I don't think I'm that difficult to find. I mean, Amber found me on Telegram, so it must be easy to find me somehow.
Alan's a busy guy, right?
Sascha Wolf (01:05:34.37)
Nice. I'm Alan Spamfilter.
Sascha Wolf (01:05:43.048)
Sascha Wolf (01:05:56.48)
Okay, then let's transition to Pixar, I would say. You should have seen Adi's face.
Yeah, I wasn't ready. But a quick one came in my mind, which I can just pick up. So we talked about security a lot. We talked about all this stuff. We forgot to talk about authentication. And just want to give two picks which in combination, I think is the quickest way to add authentication to your application. It's uberauth with odd zero.
Both are free, actually, if you use it for a few months. I mean, Uber Auth is an open source package, and Auth0 is a service that provides OAuth. So you can create an Auth0 account and just add an authentication interface. It will say it's in dev mode, but it'll be free. And once you're ready, it's like four or five bucks a month. So I would definitely check it out. I know Mixed Phoenix Gen Auth is attractive and stuff. It's a pain to manage your authentication, trust me.
Once you have a production app, you don't want to do that. Just outsource that. Buy over build, as people say, right? So, Auth0 and UberAuth, check them out. My other pick is a game that I started playing yesterday and I've been playing today. The reason why I did not sleep yesterday night is Baldur's Gate 3. It's epic. I know a AAA game, whatever. I bought the Deluxe version. That's why I got 3D.
early access and it's beautiful. If you're a D&D fan, if you're a Baldur's Gate fan, if you're just like D&D lore fan, RPG fan, play it. I think it's a genre defining game. I put in that category, Skyrim category. It's pretty epic. Definitely play that game.
Sascha Wolf (01:07:51.516)
There's one note I gotta say here because I listened to a podcast on the game. The Act 3 is very, very unfinished and very buggy. So Act 1 and Act 2 are probably really, really good from what I've heard. But it really is a let down on the later parts of the game. So maybe like definitely agreed 100%. It's like, it's an amazing game. Basically the podcast kind of concludes with it's the best game we cannot recommend yet. So maybe wait it out a bit until they kind of...
which is not uncommon for the games the studio is publishing. It's Larian Studios and the last game we published had a similar story about the end of the game not quite being there yet. So maybe wait for a few more months.
And I mean, like, bugs in the sense of game breaking, right? Like where you can't progress any further because the plot, you have plot stoppers and that kind of shit. So, but yeah, it's from what I've also heard. I mean, I haven't played it myself, but what I've heard, it's amazing. That just needs more polish.
Then you get to play the game all over again. Come on, get it now. Ha ha.
Sascha Wolf (01:08:55.704)
I'm just gonna go ahead here. So my pick for this week is honestly, I don't know. I came hopefully unprepared to this. What am I going to pick? I mean, I'm just going to pick. You probably can be edit this out. Wait, I'm going to take a note one hour nine.
Sascha Wolf (01:09:32.206)
Okay, Alan, do you have any picks for us?
Yeah, I have one pick. I don't know about you guys, but I'm a huge Metal Gear Solid fan. They have that Collection Volume 1 coming out. This is probably the only game I've pre-ordered so far. I don't know. Maybe about you guys. For me, I like to wait till the Steam sale comes up and quite cheap. But for this one, like I said, I'm a huge Metal Gear fan. So I pre-ordered this one so I can get all the content. I've been really wanting to play this game on my Steam deck.
And so now with it coming on in October, it's going to be nice and fun. And quick plug, I am coming to CodeBeam in Berlin. So hopefully we'll see any of you guys there. Just let me know. I mean, obviously, if you guys are coming, then you can find me there. You don't need to email Addy, but definitely check it out. It's going to be a lot of fun. Hopefully Sasha will also come since it's pretty much in his neck of the woods.
And I think Adi is going to try to join virtually. So yeah, if you guys are going, let us know. And then we'll try to meet up. Maybe we can see if we get some stickers or something. That'd be kind of fun.
Sascha Wolf (01:10:47.508)
Nice. And from my side, I honestly don't have any picks this week. So... Disappointing, I know. Disappointing. I just can't think of anything right now. So...
That's not allowed.
pick like a conference or something. Pick SpawnFest.
Sascha Wolf (01:11:04.248)
I pick vacation. You all should take more vacation and more rest, because I'm going to take a nice week of vacation next week, and you should do the same. Take care.
I would say Sasha has an anti-pick, Baldur's Gate 3, right? So.
Sascha Wolf (01:11:20.465)
Take vacation to not play Border Skate 3 yet.
Sascha Wolf (01:11:27.651)
Okay, what's a pleasure, Adi. Bye, Dylan.
Awesome. No, I just said awesome.
Sascha Wolf (01:11:32.116)
And I hope it will... Yeah. Go ahead.
Sascha Wolf (01:11:37.565)
I hope you all enjoyed listening to this as much as it was enjoyable for us talking about this. And I hope you tune in next time with another episode of Elixir Mix. Bye!