Flavours of busy, restrained features, and variable static views - podcast episode cover

Flavours of busy, restrained features, and variable static views

Jun 26, 202547 minEp. 178
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

In this episode, Jake and Michael discuss the nuance of being “busy”, saying no to features (and why), handling user feedback early, Laravel-powered static views with dynamic data, and building tools that stand the test of time.

Transcript

Hi. I'm Michael Dyrynda. And I'm Jake Bennett. And welcome to episode 178 of the North Meets South Web Podcast. [rock music] Nailed it. Good job, dude. How's it going? Nice. Going well. Going, uh, yeah. Going well. -Busy- -Good -... but but well. How about you? -Great. Yeah. No. Same. Same. I [sighs] I've tried recently. I I catch myself saying the same answer that you just gave a lot, which is busy, -right? -Mm-hmm. And and i- it's true. Like, it's not a lie. I mean, we are. We are busy.

-We're all busy. -But I realized after a while that I would ask people the same question, they would say the same thing. And it's like, you know what? We're all busy. All of us, we're all busy. -Yeah. -Like, so- All busy all the time. Yeah. I tried to stop saying that, but it doesn't work very well 'cause it's still typically my answer. "How are things going?" -Yeah. -"Oh, you know, bus- pretty busy. But busy work, but the good. Things are good. Things are good." You know, so whatever.

-So- -I mean, I don't, I don't know how else to -answer the question because that's- -I know. -That's how I am. -There's so many things going on. It's like -I have to pick one thing to talk about. -Mm-hmm. Uh, it's like I I could talk about a lot of things, but there's a lot of things -going on, so I'm busy. -Yeah. -There's a lot, you know? -Yeah. -We all are. -Busy. -We all- -Busy, busy ... are.

You reach that certain stage in life where you, you think... Uh, I remember thinking when our kids were little, like, "Man, once my kids can feed themselves and tie their own shoes, then things will probably slow down." And it's like and then they get older, and it's like then it's friends- -Gets harder -... and sports. -Yeah. -And you're like, "Man, after basketball season is over, then then things are gonna slow down a little bit." And it doesn't. -It just keeps going faster- -Yeah

-... and faster and faster and faster. -We're we're just moving into that phase -now with Eli playing sport and soccer. -Mm-hmm. -And now it's- -Mm-hmm Liv has decided that she doesn't always want to... I think more often than not, she doesn't want to go to the soccer games, which is fair enough- -Mm-hmm -... 'cause it's cold- -Yes -... and she's sitting around and she's -bored. And- -Sure. Yeah. Yeah ... she's not really interested in it. So because she's not participating, she

doesn't doesn't really wanna be involved. And so one week, I'll take Eli to soccer. -One week, Ria will take him. And so- -Oh, nice. There you go ... it's back and forth, and then, like, figuring out who's going where. And and now that the kids are a little bit more independent and it's a bit easier to do things. Like, before, when we'd, like, bath the kids, we want all hands on deck 'cause someone will be washing one, someone will be drying the other one, -getting them ready for bed- -Yep.

-And all that kind of stuff. -Yep. [laughs] Now now both of them can basically wash themselves, except when it comes time to washing their hair. And Eli can dress himself, so it's like you... Uh, we just watch them get in and out to make sure that they don't- -Get in there -... slip on the bath. -Yep. Yep. -You know, so that makes it easier to, like, go out during the week so that, you know, Mum can put one of them to bed or I -can put one of them to bed, feed them- -Yeah

... all that kind of stuff. And and it's not like this overwhelming chore of of having to do all of that stuff because they're quite independent already. Um, and so that that makes life a lot easier, so that we don't have to have two people here all the time. It makes it easier for for Rhea to go to the gym or for me to go out and and grab a bite or something like that, so- -Yeah. Yeah. Very true. -It's just a- -That is true. -But it's a different kind of busy, as you -say. -It is different.

-You know? -Yeah. That's right. -It's just phases- -Yep ... of busy. And then, you know, once they get to- -Exactly -... the age of your kids, at at the other end, it's, like, more professional sport kind of commitments. Not not professional, -but, like, higher level of of sport- -Yeah ... commitments, where it's training multiple times a week. It's playing multiple times a week. It's all of -this kind of moving around- -Right. Right -... where we now- -They're trying to get better. Like, when

they're younger, it's like they're just trying to play. They just, they're happy -to just play. -Yeah. Mm-hmm. And, like, at this level, they have to kinda decide if they wanna be... If this -is what they wanna do, if they don't. -Yeah. And if they do, it's like they've gotta commit to practicing outside of the -practices and games and stuff. -Yeah. That's right. Yeah. And so it's like if you actually wanna get playing time and be good, you gotta do stuff outside.

-Mm-hmm. -So coordinating those times as well and -whatever. So... -Yeah. It's all lots of fun, man. It is all lots of fun. -It's good though. -But those, for like, for Graham right now, he's 14, so it feels like the clock is starting. -Mm-hmm. -The countdown is on. You know what I mean? -It's kinda- -The countdown to college because it's very -different for- -Give as much time as we can with him -... for you guys over there. Mm-hmm. -Yeah. -'Cause what's- -Yep.

Over there, very, very common for, you know, um, kids to to pack up and go off to -college and not- -Yep. Yep -... not stay at home and- -Totally ... and be away for for months at a time between breaks and things like that. Whereas here, they, they, generally, people will still go to university where they grew up. -Mm-hmm. -And and it's like you'll catch a bus to the city to, like, go, and then you'll come back home at the end of the day. So

it's it's very different, you know, hearing those perspectives. I see Abigail, you know, tweeting about it, that they're they're running out of summers with the kids at home and the kids being around and all that kind of stuff. And it's just not something that really crosses our... my mind because short of going to the join the army, you know, like my my nephew did, you don't really... Like, most people kind of tend to stay where they are until they finish study. Not a lot of

people will travel interstate for study. Um, I think that's fairly uncommon here. -Interesting. Yeah. -Yeah. -Yeah. That is a cultural thing. -Or is this, like- -I think- -... part of the course for you guys? I think... Very, very common. Yeah. Exactly. -Mm-hmm. -And a lot of kids see it as their first opportunity to sort of escape their hometown. You know what I mean? It's like -they wanna get outta here. -Mm-hmm.

They wanna go experience the world, live somewhere different, live apart from their parents and family. Kinda have their their leap into adulthood, if you will. So- -Yeah -... which comes with the pros and cons, you know, because they're only 18, so they're still kids, man. -Yeah. -It's like- -Yeah. -... you can make really stupid decisions as 18-year-olds. You can make really stupid decisions as a 40-year-old too. -But- -Yeah

... got a little bit more life experience behind you. So, anyway, yeah. It's, uh, it's fun, man. It's, it's been a good start to the summer, and things are going good. Um, last show, when we were talking, um, we came up with, like, a bunch of things that we wanted to talk about, and so I wrote them down. And we talked about how we wanted to sort of have a little bit more... What did you call it? Like, not -consistency, but, like- -Continuity. -Continuity. That's it. -Yeah.

That's the word. Continuity between the shows. And so last time, we were talking about Wistia, talked about the new Wilber Jobs website and how- -Mm-hmm -... that w- that was pretty cool. Um, I've got a couple things we could talk about with that. Staggered CSS animations, live photos, we could talk about that. Or we could talk about where to store values for templates in static sites. That's an interesting one. -Mm-hmm. -Or defensive programming.... or time

bombed feature flags. All right, which one sounds the most interesting to you? Hmm. Time bomb feature flags I've played with in the past, and they've bitten me- -Yes -... because they don't, they don't work- -Ooh -... quite as, quite the way that I thought they would. All right, let's dive in. Let's dive into time bomb feature flags. Okay. -Should I set the stage real quick? -Mm-hmm. You wanna tell me what Pennant is? Tell us, tell all the people what Pennant is.

Pennant is a Laravel first party implementation for f- feature flagging, uh, in, in your Laravel apps, right? So Tim McDonald- -Yeah -... built, built that one out, hmm, not last year, the year before, I think. So it's a couple of, couple of years- -Yeah -... it's been around now. And, yeah, it's a, it's a first, first party, you know, it, it feels like a Laravel implementation of feature flags. Yeah, it's, um, it's a really good,

um, it's a really good library, and it's very simple. Um, so it's, you know, it's basically the minimum amount of code that you would need in order to be able to run feature flags is kinda how I think of it. So it's really, um, wonderfully simple. Uh, the couple of things that we, the way that we use it is you have... You can either have a closure that helps to give it a name. You can name the feature and then have a function that accepts a scope and then resolves the truthiness of that feature.

So you say, let's say, um, the feature is, I don't know, Ken Call Michael. It's Ken Call Michael. The, you know, one of our support people gets a emergency button on their dashboard, which if they need help, they can call Michael. And only certain people get access to this because, you know, there's people who have abused this in the past. And so we wanna start out with only giving it to managers, because managers are the ones who, uh, can escalate calls

to Michael. So what we're gonna do is we're going to thi- name this feature Ken Call Michael, and, uh, the way that I'm going to do it is I'm going to implement it inside of a class called Ken Call Michael Feature. And, um, inside of that, I have a resolve function, or sorry, resolve method, which accepts a scope, and I think typically that's just a generic, it's mixed $scope. But you can specify things like user. So I know that I'm passing a user into that scope, and it

will fail if I pass anything else. So I'll pass a user in as that scope, and then I can say user hasRole manager, something like that. And I return that, return the truthiness of that statement. So if that statement returns as true, when that person visits the page that, uh, checks that feature, right, where that feature is actually on the page, it will grab that class. It will resolve that feature, resolve that method, and then it will return a truthy or falsey, um, value. And

then that will get stored. Depending on what driver you're using for Pennant, it'll either get stored in the database, or it'll get stored, you know, in Redis or other places, wherever you might have it. -Mm-hmm. -And then at that point, it is resolved. It is not stored. It will not ever resolve again unless you delete or, or, uh, purge that feature for that person, which is great. So that's the idea, right? I can turn features on or off. I can also launch it

as, like, nobody gets it. I can just, from that resolve function, return false. And then I can go into the database, and I can say only I get it, right? Or I can release it to a beta group of users. So I can test it in production without having any fear of breakages occurring because nobody can see it except for me. So if it breaks, it's only gonna break for me, or it's gonna break for a very small group of

users. So really, really nice. Now, after having explained that, Michael, I want to hear your idea or explanation of time bombs, why you might use them, and how you implemented them and how they bit you.

Mm-hmm. Yeah. Well, I think it's, it's the, the fact that they are resolved once and persisted that has bitten me because- -Mm-hmm -... the, the time bomb nature is that I would expect that a feature flag applies or doesn't apply depending on how you've got your code wrapped by that feature flag at some point in the future. -Mm-hmm. -So the way that I wanted to use them, rightly or wrongly, last year when, when I looked at it, was to time bomb the -display of speakers for Laricon AU. -Hmm.

So, like, on some day in the future, we want this speaker to appear on the -website. -Yeah, yeah. So I don't have to remember to do it. So I don't have to be at the computer to, you know, tick a box or whatever. So I thought, yes, I will, I will time bomb that feature flag, uh, so that that speaker appears at some point in the future. Now, the problem with that was, because that was resolved once, when it resolved -the first time that it was loaded- -Mm-hmm.

-It was false -... it was like... It was false. So it went into the database, and that was it. It was just false forever. So I would have to then go in, [laughs] on that time, on that day, to then remove that flag, which- Yeah -... kind of defeated the purpose of it. -Defeats the purpose. -So that's- -Totally. That's where, that's where I got bitten by them. Other than that- -So- -... I think they work fantastic. Okay. So, so

it's probably helpful to talk about definitions of what a time bomb is. So what you've explained there is not necessarily a time bomb. A time bomb, as Martin Fowler describes it when he's talking about features and toggling, is a way for you to make sure that feature flags don't stick around for forever, -right? -Mm-hmm. So you could think of a time bomb more as an expiration date than a... Only to show

-it at this time. Now- -Mm-hmm ... I think it's worth discussing how we would actually approach your particular -problem that you're talking about. -Mm-hmm. And maybe, I don't know. I- I'm actually not sure how I would solve that with Pennant. I think I would honestly, in that instance, I would literally just put a timestamp check or something [laughs] like that. -Yeah. All right. -I would wrap it with a conditional if that -says- -Yeah ... if, if, uh, now is passed and then pass in the date-

-Mm-hmm. Yeah -... and then I would... Then that's how I -would do that probably. -... yeah, this year. This year, we put all of the, the speakers into the database, so now we just have a, like, publish date -is in the past. -Ah, so- oh, perfect -That works fine this time -... there you go. Yeah. Which is the sensible way of doing it, but last year, we kind of... The, it was all static HTML really, so we, we put all the spon- uh, the, all the speakers on

-the page that way. And so we're- -Yeah ... just expecting, like, for each one to then, t-to, to appear effectively when, when the time is in the past, but didn't work out that way. Uh, but this year, yeah. It's just a, just a field on the database that's an announced at or something like that, and we just return all of the speakers where announced at is less than or equal to now, which is much- -That makes sense -... easier way of doing it.

-Great way to do that -Don't use feature flags for that. Yeah, -no. -Absolutely. Great way to do that. So, so if we're approaching this idea of time bombs as this, as more of, like, an expiration date, um, I, I would love to talk about that just for a little bit. And, and essentially, I'll give you the scenario that we faced that had me looking back into this, which was we had a feature flag that was, you know, gate, gating a feature that we had written and I pushed it out on a Friday

-and promptly forgot. -It's time to push down -About that feature. -Yeah. Just want to push down Totally forgot about it. It didn't matter. It was like, "Okay, hey, whatever." So, uh, I enabled it for a couple users and the users of us who had it just looked at it and figured, "Well, everybody must have this," right? We totally forgot -that we did not release it for everyone. -Yeah. And so six months later, somebody's like, "Yeah, I don't know how to see, like, if

this file is timed up or not." Like, well, just use the, you know, just use the -timed up, you know, thing at the top. -Yeah. They're like, "I've never seen that." And they're like, "Well, like, certainly. Like, it's right up here. Here's where you should see it." Go into the features table. Yup, not enabled for anybody except for us. Like, ah, crap. And so what happened is we had this feature flag that was not supposed to be around forever. It was only

supposed to be for this beta testing sort of idea. And once it was good, then we needed to remove it. So the question is, how do you inform yourself when you should, you know, how do you basically put an expiration date and say, "Hey, by the time a month has passed, we should have figured out if we want this feature -or not for everybody." -Mm-hmm. It should be general release to everybody, or it shouldn't be. -Yeah. -And, you know, we kinda need to pull the trigger on one way or the other.

So I asked Tim McDonald. I was like, "How would you do this?" We had a couple ideas for how we would do it, but the way that he did it was very, uh, clever. And so I wanted to share the idea that he had, which is, uh, to put on each one of your feature classes, which again, is the way that I really prefer to do it, is to use a class-based resolution because you get all the other things you can do, this behavior, these traits that you can put on

it and whatnot. But you make a trait called is, like, concerned with expiration, you know, maybe something like that. And inside of there, um, you have a contract essen- or sorry, maybe it's a contract, not a trait. But it's, uh, a contract that specifies that you need to have a is expired method that returns a Boolean. And then what you can do is, uh, in that is expired, you can do a date. You could say now is past a particular time, or you can do other things, right? You can,

there's other things you could do. It doesn't have to just be a date, but you just return a Boolean from there. And then what you can do is you can, in your service provider, you can say there's an event that says feature resolved, I think is what it is. So what this does is any time that a feature gets resolved, even if it's out of the database, if it's grabbing it, it will look and say, um, is this an instance of, you know, or does this extend the contract or implement the contract of, uh,

you know, can expire or something, whatever. Like, what, you know, I'm using bad names here, but that's the idea, right? -Sure. Yeah, yeah, yeah. -And if it is, if it does extend that contract or implement that contract, then what you do is you check to see is it -expired. -Yeah. And if it is expired, then you can do a couple things. So, um,

you know, you could log, warn yourself, something like that. Um, but the thing that Tim did, which I thought was really cool, is there's this way that you can check to see if you're running tests currently. Have you ever seen this before? -So it's like- -The other container that's, like, is -running- -Yeah ... running unit tests or something like that. Yeah. If app dot op running unit tests. So you can do this conditional. You should say, "If we're running tests and it's expired,

then we want to throw a runtime exception that says feature has expired." So what that does then is if you're ever running a test that encounters this feature, and the feature is expired, it's going to force you to make a decision one way or -the other. -Yeah. -You either need to extend- -Extend it ... the amount of time that you have until it expires. -Or remove it. Mm-hmm. -Or get rid of it. And I love that because it does... It's not destructive. It doesn't ever mess you up in production.

Uh, you can have it log if it's in production if you want. -Mm-hmm. -Instead of throwing that runtime exception. Um, but it's a great way to ensure that any of your features that you're putting in place have a reasonable expira- uh, expiration timestamp on them and that you're forced to deal with them at some point in the future. -Um, so I thought that was pretty cool. -I like that. -Yeah. -That is a very Tim thing to do. [laughs] Mm-hmm. To put a thing in there. I've,

-I've- -So he wa- so he did... So here's the deal. He hasn't actually, like, this is not... This does not exist. You have to just add it on yourself. -Yeah. -Right? -Yeah, exactly. Yeah. -That's why I was like, "It would be cool if it was first party." He's like, "I mean, I didn't feel like there was a good..." He said, "I didn't feel like there was a good generic option to put on top of it." So-

-Yeah -... I built the tools. A lot of the users to decide how they wanna handle it, but it's not, it's not difficult to implement -it. -Yeah. -Right? You could see how you would do so. -Yeah. It demonstrates a lot of restraint on, on his part and on, I suppose, on Laravel's part in general about where you draw the line in the sand for, for what you do offer as part of the library and for what you say, "The tools are there. Go and implement it."And, and I think this is, this is a fairly good

case, use case of the tools that go and implement it yourself. I've, I've gone back and forth over the years about whether or not using those kind of conditionals in application code is a good idea or a bad -idea, you know? -Mm-hmm. Doing an, like an environment check or doing a, are we running unit tests? Or, or that kinda stuff to then trigger things because you're, you're putting test logic inside of your application code to do this kind of stuff. Erm,

I think it's fine, in general. I don't, I don't really see any reason to do that. I know that in parallel testing and things like that, we will have all kinds of conditionals that check, like, if the parallel testing token is set, then we need to go and do this stuff. And then somewhere else we go, "Okay, don't do this stuff because we are parallel testing," and, and things like that. So there's definitely cases, I think, where doing that kind of runtime, testing time logic is good. I think

forcing you to, you know, blow up your... [sighs] It depends on how strict you are on your continuous integration. Like, if you're running this in CI and it fails because somewhere between where you pushed a pull request -into GitHub and some- -Mm-hmm. And, and when the CI ran, your, your test suite is now failing because of this expired token or this expired check, but it's unrelated to the pull request that, that was pushed up. So I think that's, like,

that's the one thing that, that sticks to me. It's like, okay, yes, we need to do something about it. It is now impacting on this unrelated thing, and it's, you know, a team decision. What do you do with that? Is someone now tasked with going immediately and, and updating that? Do we... You know, it, it may not be a decision that gets resolved straight away, depending on the size of the

organization. It, it might be, like, you as a developer or as a founder, you can go like, "Yeah, I'll just kick that can down the road a week," or, "I'll go and remove all of those feature flags, and this is now just a feature that's part of the platform." So yes, it does prompt you to do that, but sometimes that decision -involves committees. It involves- -Yeah ... product teams, product managers, things like that. You've gotta go ask.

You've gotta go wait. They don't have an answer. They've gotta go chase it up with -someone else. -So now you have a blocked PR, yeah. And meanwhile you've got a blocked PR and a failing test suite, and all of that -kinda stuff. So, you know- -In fact, every PR is blocked, right? If you had multiple PRs out there, all of them are blocked. -Mm-hmm. Yeah. -And every single person is trying to scramble to figure out what do we need to do with this.

Yeah, yeah. And everyone's going, "Oh, this is failing. Retry fail tests." Like, 'cause they're like, "Oh, this wasn't supposed to fail," you know? Es- especially, like, we get into situations at work where the, the test suite will just be flaky. Erm, and it's just over time, the, the construct of, of the application has changed where, you know, you've got factories that, that are resolved in a certain way. Which is okay when you've got 100 tests, but when you've got 500 tests

or 1,000 tests, those factories can, like, step on each other. You might not have something that's unique, so over enough iterations, you end up with collisions and things because you don't have the, like, fake, faker Unique applied in there. So there's, like, all these different cascading arbitrary failures that you might not even look at it for a couple of days- -Yep -... until someone goes, "Hey, this is, this is failing." So I like the idea in theory.

-Mm-hmm. -I think whether or not it works depends on the kind of company that you're in and how quickly they respond to that. Like, if you, and, like, whether you put that in there at all, uh, really comes down to how quickly someone is going to respond when... It may be a case that you log, you know, for two weeks or something before the failure, erm, even if you are running in test so that something bubbles up somewhere that hopefully someone would see. Erm, but yeah.

-That's a l- -Yeah, you're, you're- ... long-winded way of saying that, like, I think in general, I agree with the idea. I like, I like the idea of putting something [laughs] that explodes in, in test. Because that's something that at some point in your release cycle, whether it's during development locally or as part of CI or deployments, like, something will blow up because of that. -Yeah. -Erm, and, and what you have in place to

work around it. You know, okay, we can just merge this PR anyway knowing that this is, erm, -unrelated to that pull request. -Yeah. If you do, if you do automated deploys, it's a bit trickier. Erm, it depends on, like, if you do... I know with, erm, Laravel's testing stuff, you -can --fail on your test. -Mm-hmm, mm-hmm. And, like, it will f- after the first fail- like, if that's the first failure and it doesn't get to something else-

-There's just stuff there. -Yeah. Yeah, okay, so this is unrelated to, to my failure. I'm gonna, you know, ship this anyway. Oh, whoops. There was a, some error further down in the test suite that didn't get picked up 'cause we bailed out on this thing. So... -Yeah. -You know? -I'll say that the- -Rest reward, I guess. Yeah. The, the concerns that you bring up are the s- very same concerns that Andy Hinkle had

when we were going to implement this. He was like, "I don't like the fact that other developers are gonna have to deal with a feature flag before they can merge their stuff." So we came up with some ideas and some solutions. The one thing I will say too, though, is that this, I feel like, follows the convention that has been brought about in many different... You know, like we talked about Nuno's, um, thing where it's, like, just here's the best practices applied to the app service provider.

-Mm-hmm. -Where it's like, disallow n+1 queries or disallow lazy loading or, you know, those assignment overflow things or whatever. Like, those, those sorts of things that only fail if you're in local, if you're in your local environment. You know what I'm talking about? -Yeah. Yeah, yeah. -So, like, it'll check those things. It's not gonna blow up in production. It's not gonna blow up in your face. If you happen

to ship it to production, it's gonna be like, "Eh, okay. Just let it go." But if you're in local dev or in testing, it's gonna blow up in your face and say like, "Yeah, you can't do that." You, you can't- -Mm-hmm -... you know, do that lazy load stuff. So this sort of falls in line with that to me. Um...However, it's not a yes or a no, or an always or a never. It's, it's only based on some time-based

thing a lot of times, which is... So it's not a right or wrong. It's just like if you happen to be the guy who runs it just before it expires, or right after it expires, then you're screwed. You're the one who has to deal with it. So okay, so how do we address this? Well, two couple... Two, two different ways I think we could deal with it. Um, one is that you could, if you're running, uh, your CI on a regular enough basis, you could start dropping warnings a month in

advance of the expiration, right? So you could say, "If it expires in the next 30 days, throw a warning on the tests. If it expires in the next..." You know, if it's, if it's in the past, then go ahead and throw a failure. You know, something like that. So that would allow you to be notified of it ahead of it actually expiring, so that you could fix it. Um, and like, you know, you see it, it's, it's erroring, or not erroring but it's throwing a warning, and you're like, "Oh,

okay. I should probably make an issue for that so somebody can fix that or make a decision." We have 30 days to do so. The other thing that we talked about is making a command that runs once a day at like 6:00 AM, something like that, that runs through the features, checks if any of them are expired and if they are, sends off an email or sends it or creates an issue, or whatever you might have that says, "Hey by the way, these features are expiring within the next 30 days or the

next 7 days," or whatever. Uh, or they are expired and these need to be addressed, and that's it. You know, so there was... That was, there was a couple options there. You could say it doesn't ever fail tests, it just sends out a warning to let

somebody know that this needs to be addressed. Um, so there's a couple different ways you could do that there that I could see being effective that would not necessarily block the team, but could inform a project manager that these are something that we need to prioritize within the next cycle. Kind of, you know, deprecation warnings I guess for features. Yes, exactly that. -Mm-hmm. -Yes, correct. Yep, yep.

Yeah, and I think realistically that's the only way to, to deal with it. And if, if no one's gonna pick up the deprecation warnings for the feature flags like that on a, you know, across a team, across an organization, you know, if you're involving all these different p- all these different people, then

probably have bigger concerns to, to worry about. You know, at least sending that email or that notification in Dislike or whatever else that happens to be from that scheduled job, scheduled task, is... You know, you've got to address it in some way. Um, and if it goes to enough people, someone... Well actually, if it goes to too many people everyone's gonna be like, "I thought someone else was gonna deal with it," and then you've got to be -careful there as well. -Yeah.

So yeah, keep the, keep the list small but make sure it gets actioned, I guess is the -main thing. -Exactly. But again, comes down to the team and, like, someone actually taking ownership o- over that. So -yeah. -Yep. -Good, uh- -Yep, you got it. Good, good problem. Um, I think good, good solution to that problem as well. Awesome. Yeah, thanks. I, it was, it was a fun one to kind of run down and it was... Uh, yeah. A couple different approaches there, a couple different concerns, but I

was happy with where we landed on it, so yeah. Stoked about that. -Mm-hmm. -Okay. Since you talked about your, um, your speakers on Laracon, um, I think this is a good transition into this other part which is this, where do you store values for templates in a static view? Okay, so let me pitch it to you this way. Let's say you didn't have a database for those team members, or not another team members, for those speakers, right?

Um, because locally you are going to do it and you don't want to have to like... How do you, how do you populate your database locally and then push that up to production without having to have access to the production database? You can't really do that. It's like I know what the values need to be, they're not necessarily dynamic, it's just I- I don't... Where do I store them, right? Do I... What are my options? If I, if I can't put them in a database, where are the other places that

I could put them? So I actually came up with one just as we were talking here, but there was a couple options here that, that were thought about, right? One is you could literally just dre- like create a component and then in Blade, just you don't even bother doing a loop. You just put in the values. -Yeah. -Right? That's it. Create a component, put the values in, that is your database essentially, right? You just- -Mm-hmm -... write them all out in the blade, and

that works. That's fine. Like you just basically, your component is going to have locations or values, like the values that you would normally store in the database are gonna be essentially like arguments to that component, right? So like name, image source, um, title, announcement date, right, all those things. Right? Those are gonna be, those are gonna be stored like in the Blade file. -Yeah. -That's one way to put it. -Yeah. -That's one spot to put it.

-Yeah. -Um, can you think of any other spots you might, you might put these things? I can because this is what we did last year was- Ooh, okay. I wanna hear, I wanna hear. I want wrong answers only. -We, uh- -Wrong answers only. -Wrong answers only [laughs]. Yeah. -Yes. What were the other places you could -put it? -We created, we created a YAML file that we -hosted in GitHub that you had to- -Okay ... in a JS, it was a secret JS... No [laughs], I'm joking.

-I was gonna say, oh dang. Okay. -You said wrong answers only. -That's crazy [laughs]. -You said wrong answers only. I- I, at first I thought you were being serious. I was like wait a second, do you really? Okay. All right, all right. A YAML file in- -No, we- -... a JS that you were pulling in R. -In a JS. -Fair enough. -That's right, yeah. -Yeah. -So if anyone wants to go and- -And then you used Sushi. ... uh, and scan. Sushi. Yeah, to use as an- Used, uh, Caleb Porzio's Sushi package, yeah.

... eloquent database. That's right. Uh, no we just, I just put all that stuff -inside of like a config Laracon.php. -Okay. And it was just an array of speakers which was keyed by... Actually, I don't think it was keyed. I think it was just an, an array that we then pulled out and we, you know, we collected it. We put it in a collection. We sorted it by announced. We filtered ones that were not, you know, didn't have an announced in the, in the past and that was it. That's, that's how we did it.

-Yeah. -Um, and then I think w- we just used, you know, Cloudflare to cache that so we didn't... Well, you know, obviously the page gets cached so it doesn't have to hit the origin server to, to resolve that in the future. So yeah, that was, that was it really. Yeah. Uh, that works pretty good. So, like, you could put it in the config. You also, if you're being a little bit crazy, you could just chuck it into the

-controller. Like, if you wanted to- -Mm-hmm. Yeah ... just inline an array in the controller, you- -Yeah. Sure -... could kinda put it in there. Uh, that's one way to do it as well. Um, so, uh, my, my junior-ish developer, he's actually... He's Landon. Landon is his name. Um, he played basketball a little bit last year at Laracon with me right afterwards. There was a couple dudes that we all played. Me, David, Hemphill, Landon, and then

three other dudes that absolutely smoked us. It was really fun, but kinda crazy. -[laughs] -Landon's a great basketball player, junior developer though, and he's, he's figuring stuff out. And so for him, he ini- or initially just put it, like, in the controller. Like, he actually had a method for each. Like, so we had, like, four locations that we were trying to, like, you know, deal with. And so what he did is he put, uh, a method in, in the controller.

So you would have, like, a, a value being passed into the controller, um, like, uh, you know, in the, like, the array that gets passed in to the, to the -view. I'm sorry, to the view. -Yep. Mm-hmm. And he would say, like, "Location one, Fat Arrow, this.get('location1')." And then say, "Location two-" -Yep. -"... this.FatArrow.get('location2')." So he was just calling private methods inside the controller that were sort of then -returning these arrays. And I was like- -Yep ..." Hmm,

that is fin-" Like, it works. It's probably not how I would do it, but it -works. And so I- -Yeah ... was like, "I'm wondering..." You know, config file is the first thing that came to mind. But for some reason, I remember when looking at it, there were some reasons why it wouldn't have really worked in a config file. And I think partly because he was doing some PHP stuff inside of that config file, and, like, it would've been weird to do it there. Um, but

the other thing that I'm wondering here is this. If you didn't want to store it in a config, what if you just put it in a SQLite database and then shipped the -database up? -Yeah. Yeah, -totally. -If you put that in somewhere? Like, could you... Where would you put that, though? Would you... You'd put it in the storage file or something? I don't know how that typically works. If you put it in the storage, you have to, like, symlink it or something weird like that if you're using

-Envoyer. -Yeah. I would just, just put it in the database, 'cause that's, that's where the SQL files go by default. -If- -Okay ... you know, if you, if you, if you do a Laravel new and you say you wanna use SQLite, it will create a database/database.sqlite file inside of storage. Uh, inside of the database folder, and then you just commit that to -version control and off you go. -Yeah, 'cause I'm... As, I'm sure initially it's probably.gitignored maybe?

Hmm, not a... Oh, yeah, maybe database.sqlite specifically, but you -could just remove it from there, like- -Totally. You could. Just because Laravel puts it there by default doesn't mean you can't change it. -Um- -Absolutely. Yeah. Yeah, shipping, shipping sqlite is fine. Um, who, who was it? Like, was it Aaron Francis was talking about that for, for, um... I think for his aaronfrancis.com. He's, he ships an sqlite file or something like -that, so. -It seems like the right place to do it,

-right? I mean, like- -[laughs] ... you literally have, you have the structure in there. You can pull it using -your, uh, you know, using models and- -Mm-hmm -... all that good stuff. -And, you know- So it's like, I don't really see a reason why you wouldn't or why you couldn't. SQLite is, is made to be small and portable like that. -Every, you know- -Mm-hmm -... the, these things, every- -I mean, the problem is it can fill up -... everyone's iPhones- -It's just a flat file, yeah.

Everyone's Android file. Yeah, it's just, just shove it all in there. Yeah. -Yeah. -Um- -Yeah, so I think- -I mean, the other thing you could probably -do is like a- -... that's, that's an interesting third -option. Yeah -... a document store. You know, something that writes JSON to a file, and -do that, I guess, with, like- -Yeah, but the SQLite thing seems way

better to me. Yeah, as long as you have... I mean, as long as you can set up... You know, you just have to make sure that every person, each person that's looking at it, uh, when they're trying to develop stuff, uh, that they map... Uh, you know, they can open TablePlus to that sqlite file or whatever, right? So- Yeah. Yep. Yeah, that seems like a good way to do it though. Seems like a pretty good way to do it. Um, portable, light. It's still a mi- it's still a, uh, you know, queryable

-entity. Um, you don't have to write- -You could be- You don't have to write, like, factories or anything for it. You could just... You know, you just ship it. You ship the actual data up. -Yeah. -Yeah. You could open up TablePlus and use that as your, you know- -Totally -... as your admin interface- -Yeah -... to put stuff in there.The only- -Absolutely, and you've got- -... the only other thing that, th- ... version control on and everything, you know?

Yeah, yeah. I mean, the only other thing that you might do that's probably a little bit more approachable in terms of version control is just a, like, a CSV file, -and then use- -Yeah ... Switchy to, to, to manage that. -Yeah. But I like the- -Because then- -... SQLite. I like the SQLite option. -Yeah. The ISQL- -And I, I'm not pushing that direction -... is definitely nicer from a, from a dev

perspective. If, if you needed, like, someone else, you know, someone from product or someone from sales or marketing, whatever, to be putting data in their CSV would be fine. And just like, "Here's the updated file." Yeah. -Yeah. -"Drop it in, overwrite, replace it." You -know? -Yeah, it's only developers working on this one, so I think SQLite's gonna be the solution there. And I think that's, um, that's a really great way to do that. So, uh, we're gonna move towards that,

actually. That's w- exactly what we're gonna do. We're gonna end up doing that precisely. Love it. Love it. Awesome. Okay, um, what else we have here? Live photos, staggered CSS animation, defensive programming. What do you think? Hmm. So, uh, Matias... I can't say his last name. Starts with a G. Guimaraes, I think. Uh, he's got a defensive Laravel course coming to Laracasts at some point, so it should be cool. I saw Jeffrey tweeted about that, like, today, I think. Yeah.

Yeah. Yeah, he, um... De- definitely check that out if you're a Laracasts subscriber. I, uh, I watched his... -It was Event Sourcing Tour- uh, series- -Mm, yes ... that he had on Screencast. That was, that was really good. He did a, a good job of that, so I'm, uh, I'm keen to see his, um, his defensive Laravel stuff. Because he, he works at, like, a payment provider or -something over, over there- -Oh, interesting ... where he lives in, pretty sure, Brazil. -One of the- -Okay

... Portuguese slash and/or Spanish-speaking nations. Sorry, Matias. -But, uh, yeah, he, um- -That's right, that's Portuguese, right? -Yeah. I- -Yeah, he's a- Did I tell you about that, right? When I said- -Yeah, yeah -... when I thought But I couldn't remember if he was from Spain or from Brazil. But I know in -Brazil- -Oh, gotcha -... they speak Portuguese. Yeah. So- -Yes, indeed. Um, yeah, he...So, he does some very intense things, uh, in terms of, like, the

extremes of what you can do with Laravel, so I can't... You know, he'd be a, he'd be a... You'd be hard-pressed to find a better teacher for that kind of Laravel at scale type of thing. So, yeah, keen to check- -Yeah -... that one out when it drops. That'll be really good. I'm sure he'll have some excellent sort of tips on using Laravel tools in order to be sure that you can catch things if they happen terribly, if they happen to go terribly wrong.

We had something today where, um, it was, it was the sequence in which something was working, so we were reading an email from an email inbox, we were creating a record for it, and on that database we had a unique column for the ID of that item from that inbox. So that item from that inbox was given a unique, like, Outlook message ID. And so it's, you know, it's a GUID. And so it's, it's unique. You cannot create another one with that same GUID.

However, the step after we created it was to move it from that location, that folder, to another location. If that failed, right? So you'd move it from the inbox to a folder called Processing or something like that, right? So we create the record, and then we start to process that email. We read the body. We read the subject. We do some, you know, guessing as to where we think it needs to go and basically have our own really

intelligent rule system that we can build up off of that database record, right? So you create the record, and then you send it to processing. Well, if that sending to processing fails for some reason, which sometimes is this weird race, race condition, if it fails, then the email doesn't move, and when the inbox gets scanned in the next minute, it tries to pick that up again and create the record. Well, since you have a unique ID, it fails. So

yeah. It, it's like just using simple things like a database transaction around those two pieces, right? Create it, and then move it. And if it fails while moving, roll back the creation so that it can try it again next time without hitting a unique constraint. So those are the sorts of things that we're talking about here, right? These, you can't anticipate everything that's going to happen. You don't know all the different failure points, but you can certainly wrap

something into database transaction and roll back if something fails. You can do that. And that's, you don't have to know everything. You just have to know if anything fails in here, roll back. Don't leave this unfinished, weird state, um, that you're gonna have to contend with later, especially if you have- -Yeah -... constraints around unique values. So I hope in, in, you know, in his course he, he covers some of those things or, you

know, like the rescue function in Laravel is so insanely awesome. Where if there is a failure while you're attempting to do something, you can provide a default return value and just continue the program running as if nothing failed, right? Those, that's incredibly helpful. So Laravel has a ton of tools to help make it more resilient and more bulletproof if you know they exist. So I'm sure he'll- -Yeah -... cover all that stuff and do a great

-job doing so. -Yeah. One, one thing I've been caught out with by that Rescue helper in the past is typically I'm wrapping something in Rescue because I don't wanna know about it, and I always- -Yeah -... I, I have on more than one occasion forgotten to set the report flag to, to false. Uh-huh. So I still, I still get the exception to bubble up, and then I go like, "What is this?" And then I, I, like, I put the Rescue in there, and I go, "Ah, I forgot,

forgot the, to report." Because the, the place that we mainly use it is when we are trying to parse dates using Carbon or the- -Oh -... or the date facade. Because, you know, you guys use, um, month, day, year, and we use day, month, year. -But- -Ah, yes. Right ... if you take something that's day/month/year and you throw that at date parse, because that's how we would re-enter it into a UI. Yeah. When you take day/month/year and put it into PHP, PHP assumes that it is -month/day/year. -Yeah.

And so what you end up with is something that's, like, 13/3/25. -Yeah. -And then Carbon goes, "Thanks." Freaks out. Um, so yeah. We, we've got in a number of places where we're handling that, you know, a date create from format, and then we explicitly tell it, like, "This is -day/month/year." So that- -Yeah

... it goes, "All right. Yeah, this is, this is the right way round." Um, and then we fall back to just doing, like, a date pass in case something comes through as year-month-day or whatever else and then, then gets picked up that way. But yeah. When it, when it hits that first Rescue, uh, callable and you don't have the report, then we still get the exception bubble up into, um, our observability tooling. And it's like, "Oh, yep. I don't really care about -that," because- -Yeah

... it's, it's... Like, it will, it will catch the exception from the Rescue, report it, and then go to the f- the fallback, so you're, like- -Then it'll continue on, but yeah -But, and then you go, "But this worked. Why am I...? Oh, okay. Yep. Gotcha." -So don't, uh- -Yeah, exactly -... don't miss that one. [laughs] -I'm surprised that there's no, like, localization thing for Carbon where you can basically just tell it at the top

level, "Hey, we're in Australia. Please handle dates accordingly." Yeah, yeah. Probably. Probably is and we just miss it, but, um- -Yeah. Maybe -... no, 'cause this is an underlying PHP thing as well. -Like- -Oh, gotcha ... if you were to do... Yeah, if you were to do, like, a create, whatever the underlying PHP function is, it will do the same thing. -Got it. -The, the- -Yeah -... the correct approach for that is to -use hyphens instead of slashes. -Ah, interesting.

But no one, no one here is going to enter the dates with hyphens instead of slashes, -because that's just not what we do, so. -Yeah. -Like, that is- -Yeah -... I mean, I assume that's- -We don't, we don't do hyphens either. Yeah. I assume that's, like, the workaround in, at the language level. To

be like, "Oh, yeah, you can do this as long..." But you, you're not gonna tell, you know, users of your platform who have become accustomed to using slashes to use hyphens in your application wherever else -it's just handled, so. -Yeah. Yeah. Absolutely. Well, hey, dude. I think we have a couple things left to talk about next time. Um, we could probably talk a little bit more about defensive programming and some examples that we have. We could talk about...... staggered CSS animations, which is

interesting to me. This is when you go onto a page and you want, like, this effect of when you hit a certain observability point, and there's a, what's that called? Interaction observer? It will animate something in into view. But if you have, like, three paragraphs of text or something like that right following each other and you scroll down really fast, you don't want that whole block to animate and at the same time. You want them to animate in, like, a -PowerPoint- -One after, yeah

-... like, one, two, three. Yeah. -Mm-hmm. Which is a little bit tricky to do. And so, um, I think, uh, motion.dev allows you to do that. We figured out how to do that. I still have to implement it. Uh, and then this idea of how do we, how do we accomplish live photos on the web, where

if you roll over something, it kind of moves the photo. It kind of gives you this motion, where it changes from a photo to a video while you're rolled over it, and -then- -Yeah ... and then when you roll off it, it, it stops doing that. -Interesting. -So found some interesting stuff about that. It'd be, uh, I'd love to kind of talk that through with you and see what -your thoughts are- -Mm-hmm ... on that. So

-next show, folks. Come on back and- -Sure ... um, you know, hey, uh, to go along with the, uh, the news of, uh, Steve and Erin breaking up, I, I gotta let you guys know that, um, Michael said he's leaving the podcast, and it's, he's just leaving it to me. He said, he said he's giving me -everything. Just take it. -[laughs] I'm paying, I'm paying him 50% of what it's worth. -So [laughs]- -50% on anything is nothing. -Since we haven't had a sponsor. -[laughs] Sorry.

-[laughs] -We are, we- -Since we haven't had a sponsor in, like- -[laughs] ... years, I'm getting a steal on this thing. -That's right. I said, I said to Aaron- -Oh, man ... that, uh, that the, the unsponsorable, the unsponsorable comment was ruthless. It was fair, but it was ruthless. [laughs] -Oh, so funny. So funny. Oh, my. -He'll be fine. -Well, anyway. -I think, I think he's for himself. Yeah, I agree. I agree. No, totally, totally. He'll do great. And I think Steve

will do well too. I mean, I think people knowing that he's available, I mean, heck, when I heard that he was available, I'm like, "Oh, geez. I have a couple things I could have him do actually." Like, actually- -I said how- -... one specific thing that I thought of that I was like, "I would love for Steve to do this," but I knew he wouldn't have -time. -Yeah. -So maybe now he does. -Maybe. Get into it. 'Cause I said, "How

long before he'll... How, how long before he lands on the Lara ship?" So... -[laughs] Right. -Get him before it's too late. May- Who knows? Maybe that was, uh, maybe that was part of his, his calculation. Maybe he was like, "You know what? I can have a job over here if I really wanted one." -Mm-hmm. -"So maybe I'll just do the job thing for a -bit." Who knows? -Yeah. Not making any, uh, assumptions here. Hey, folks, also if you have not bought your

Laracon tickets yet, it's might be too late. But if it's not, you should definitely go buy them because Michael and I would love to see you there. We're gonna doing some interviews there. We're gonna be enjoying the show, watching all the talks, and we would love for you to say hi. So please stop by and say hey. Look for, uh, the really tall guy and look for the handsome Australian with the, uh, other cursing Australian next to him. That will be Aaron. Uh, OG, OG Aaron. -[laughs] -OG Aaron.

[laughs] OG Aaron making an appearance again at Laracon US. -Yeah. -He's gonna be a riot. I can't wait to see him. Fun. -It'll be good fun. -Awesome. Episode 178, folks. Thanks for tuning in. You can find us at North Meets South.audio/178. Hit us up on X or on BlueSky at Jacob Bennett, at Michael Dorando, or at North South Audio. And, uh, if you liked the show, rate it up in your podcast app of choice. Five stars would be amazing. Thanks, folks. If you'd like to sponsor us,

also talk to us on those channels. It won't happen. But if you'd like to, we'd love for you to. But until next time, we'll see you. Oh.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android