Speaker 1: Hi, everyone, Welcome to another episode of Ruby Rogues. I'm
Speaker 1: David Kimura, and today on our panel we have Matt Smith,
Speaker 1: Luke Sutters II, and we have a special guest, Kyle
Speaker 1: da OLIVERA. Do I say that right?
Speaker 2: That's Delivera Doliver. Yeah.
Speaker 1: So, Kyle, would you mind telling us a bit about
Speaker 1: who you are, who you work for, and some of
Speaker 1: the things that you're doing.
Speaker 2: Sure. My name is Kyle. I've been working for a
Speaker 2: company named CLEO. Let's say Legal Practice Management SaaS software.
Speaker 2: It's based out of Vancouver, Canada. It makes practice management
Speaker 2: software aimed at lawyers. We're looking at transforming the legal space.
Speaker 2: Our mission is to transform the practice of law for good.
Speaker 2: There's a nice little double upon for there. And it's
Speaker 2: been really interesting seeing some of the changes in legal
Speaker 2: that we've kind of made an impact with over the
Speaker 2: last few years. I've been working on Rubyan rails for
Speaker 2: the better part of the last decade. But when I
Speaker 2: started working on rails it was rails versions zero and
Speaker 2: I've been upgrading rails ever since and so now finally
Speaker 2: up to rail six and so touching all of the
Speaker 2: major versions. My major focus at CLEO, which I've been
Speaker 2: at now for eight years has been on the back
Speaker 2: end infrastructure side of things. So the main focus is
Speaker 2: scalability for the codebase, but also in the terms of
Speaker 2: the organization, like what happens when we have two hundred
Speaker 2: developers working, what happens when the dataset sizes are to
Speaker 2: the size where we can exhaust regular integers and we
Speaker 2: need to actually go into like vacants. We look at approachability.
Speaker 2: How easy can we just take a new developer and
Speaker 2: dump them into the codebase and have them up and running.
Speaker 2: Because as things go to scale, there's obviously new patterns
Speaker 2: that need to be adhere to that you know, we
Speaker 2: don't necessarily need to focus on with small project, but
Speaker 2: we do need to focus on for large projects, and
Speaker 2: my team has focused a lot of that to making
Speaker 2: the effort and experience for all of the developers easy
Speaker 2: and fast.
Speaker 1: Yeah. Absolutely. One thing that kind of rings true is
Speaker 1: you always have to think about scalability when you're developing,
Speaker 1: but don't actually write for scalability when you're developing. So
Speaker 1: keep it in the back of your head saying is
Speaker 1: this going to come back and bite me later or
Speaker 1: is it you know, a really non issue. I remember
Speaker 1: one time I had a situation where I was soaring
Speaker 1: just three kilobytes of data in a database, and I thought, Okay,
Speaker 1: this is going to get used a little bit. They
Speaker 1: were images, so you can kind of see where this
Speaker 1: is going. I'm like, you know, that's not a big deal.
Speaker 1: It's only three kilobytes. But unexpectedly the consumers loved the
Speaker 1: feature that it was supporting. And now that single table
Speaker 1: is over thirty gigabytes and it had as millions upon
Speaker 1: millions of records. I'm like, oh, that was an unexpected
Speaker 1: But I guess that's kind of where I did not
Speaker 1: think of scale at the time or proper way. So
Speaker 1: introducing that kind of technical debt kind of painted us
Speaker 1: in a corner because now transitioning away from that model
Speaker 1: is going to be a pain when you're dealing with
Speaker 1: that much data.
Speaker 2: Yeah. Absolutely, it's hard to know what you don't know.
Speaker 2: So if you don't think about the scale at that
Speaker 2: point in time, it's hard to know what problems you're
Speaker 2: even going to run into.
Speaker 1: So you gave a talk last year about death by
Speaker 1: one thousand commits. Could you give us a high level
Speaker 1: overview of that talk and kind of some of the
Speaker 1: things that entails.
Speaker 2: Yeah, So working at CLEO, the code base is quite large.
Speaker 2: We have tens of thousands of commits that we go through,
Speaker 2: and it's really easy to see patterns of developers working
Speaker 2: on features. The features go live, and at some point
Speaker 2: in the next six months a year, those features come
Speaker 2: back to bite us. So as like the first commit
Speaker 2: is great, the tenth commit is you're starting to notice
Speaker 2: some things. By the hundred, there's maybe some problems. And
Speaker 2: by the thousands, lat thousands commit on it. Right, you've
Speaker 2: stopped because now you have to completely refactor and rebuild
Speaker 2: a lot of this technical debt that you introduced. So
Speaker 2: my talk was talking about some of the lessons that
Speaker 2: we've learned. And although these the lessons are very specific
Speaker 2: to specific problems, there's kind of a generalized idea of
Speaker 2: what some approaches that you can take to dealing with
Speaker 2: technical debt in your own projects. If you are able to,
Speaker 2: for instance, keep if you're able to automate technical debt
Speaker 2: away entirely, well, now there's a whole classification of problems
Speaker 2: you no longer need to think about, and you can
Speaker 2: feel confident that those are just automatically protected and if
Speaker 2: you are cleaning up after yourself as you go and
Speaker 2: making it easier when there are curve balls being thrown
Speaker 2: at you, Fixing technical debt and dealing with it when
Speaker 2: you hit scale doesn't have to stop you entirely. It
Speaker 2: just becomes a constant, small tax that you pay. But
Speaker 2: if you invest in the tools, you can actually start
Speaker 2: moving faster even as you.
Speaker 1: Scale right, and so would you mine also explaining what
Speaker 1: technical debt is, what would you consider technical debt and
Speaker 1: what are some things that you would maybe not consider
Speaker 1: technical debt? Kind of like some debusting myths about technical debt,
Speaker 1: I would.
Speaker 2: Say technical debt is like accumulation of decisions that are
Speaker 2: made while coding that you eventually need to correct in
Speaker 2: the future. And as developers, I think we're always making
Speaker 2: these decisions. Can we cut a corner here to deliver
Speaker 2: a feature out a little bit early? And I think
Speaker 2: those are like technical debt isn't bad. I think when
Speaker 2: you are willing to get something in front of the
Speaker 2: users and deliver value earlier by incurring a little bit
Speaker 2: of this technical debt that you then have to clean up,
Speaker 2: I think that's totally okay. But I think technical debt
Speaker 2: often comes in the situation of developers making a decision
Speaker 2: that a framework needs to be super generic and it's
Speaker 2: got a little bit speculative, and then they come to
Speaker 2: implement something in the future and it's just really difficult
Speaker 2: to deal with because it's so generic and hard to
Speaker 2: understand that new developers have to then unpack that and
Speaker 2: wind it back just to implement something new in it.
Speaker 2: Some things that I think are not necessarily technical debt
Speaker 2: can kind of come from maybe decisions that actually made
Speaker 2: sense at the time and aren't necessarily any cutting a corner.
Speaker 2: So I mean, it may make sense to build a
Speaker 2: system that is very generic, and maybe that is the
Speaker 2: correct choice, and you build through and then things change,
Speaker 2: and when things change, that's when you might have to
Speaker 2: have like the technical debt comes back. But until the
Speaker 2: things change, it actually might not be I think that's
Speaker 2: a bit of like a generic answer. But it's hard
Speaker 2: to pin down a concept like technical debt because almost
Speaker 2: everything we write is debt of some form.
Speaker 1: Yeah, I definitely have to agree with that. So where
Speaker 1: are some of the real world examples that you guys
Speaker 1: have experienced over your years, where at the time you
Speaker 1: made a decision and you or the team thought like
Speaker 1: this was a great choice, this is the right way
Speaker 1: to do it, but then later you found that it
Speaker 1: became more troublesome or more of a headache than it
Speaker 1: was worth.
Speaker 2: One of the things that popped up is actually something
Speaker 2: that you know, we decided on because the rails community
Speaker 2: pushes for and this is what comes out of the box.
Speaker 2: So if you think about RAILS migrations, if you think
Speaker 2: about how they're often applied, if you think about some
Speaker 2: examples that you've worked on, there are often times where
Speaker 2: you use something like a tool like Capistrano, which deploys
Speaker 2: some code and as part of the code database, migration
Speaker 2: gets run. And for projects that's fine, that's like a
Speaker 2: for most small things like that, migration that runs is
Speaker 2: fast and it's not a problem. But so this is
Speaker 2: an example of a decision that we kind of were like,
Speaker 2: let's just inherit what the community uses. But as we
Speaker 2: started scaling out, we started encountering problems with it. So,
Speaker 2: for instance, a table that if you ran a migration
Speaker 2: on it took thirty minutes. This means that our deployment
Speaker 2: took thirty minutes. It also timed out so we lost
Speaker 2: all of the context of it. But also during this
Speaker 2: period of time, the table locked, so any developer or
Speaker 2: any queries that started going to that table stopped being answered.
Speaker 2: So all of our servers shut down, and we couldn't
Speaker 2: kill the altered table because it was already mid progress.
Speaker 2: And after it finished, we now had a table in
Speaker 2: UH with like a new state, but the code hadn't
Speaker 2: actually finished deploying, so now we're running into different problems.
Speaker 2: So this is a little bit of a decision that
Speaker 2: it makes a lot of sense when you're small, like
Speaker 2: go really quick because you can, and it makes sense.
Speaker 2: But when you hit a certain piece of scale, well
Speaker 2: you can no longer run with those assumptions and you
Speaker 2: need to change those. So a new process needs to
Speaker 2: be built. And for database migrations, we need to build
Speaker 2: them in a way that are like entirely asynchronous to
Speaker 2: a deployment process.
Speaker 3: Thirteen minutes is a that's quite a migration.
Speaker 1: Yeah.
Speaker 2: I think the table, this table that we run uses
Speaker 2: us stores a little bit of all of the activity
Speaker 2: that users do, and it was like the first table
Speaker 2: we ran into that it exhausted like thirty two bit
Speaker 2: integers and we needed to flip the IDs to be Biggins.
Speaker 2: We didn't think that would be a problem either, and
Speaker 2: it's it's leaps and bounds bigger than any of the
Speaker 2: other tables we have in our system.
Speaker 3: I'm going to ask you of this question now, which
Speaker 3: is how do you make your system capable of asynchronous
Speaker 3: table migrations.
Speaker 2: There's actually there's good question, and there's actually a lot
Speaker 2: of tools that exist that we don't necessarily need to
Speaker 2: build ourselves. GitHub has a tool called ghost. There's another
Speaker 2: tool by Percona in the Percona Toolkit. I can't remember
Speaker 2: it's like maybe online schema replacement. Can't remember the exact name.
Speaker 2: But the general strategy is to instead of changing a
Speaker 2: table with like an altered table, you actually create a
Speaker 2: brand new table, populate that table with various mechanisms. Some
Speaker 2: of them use triggers, some of them use the binary logs,
Speaker 2: get the table to like a table that's in sync,
Speaker 2: and then do quick renames. And so you rename the
Speaker 2: table to be the old one to be old. You
Speaker 2: change the new table to be the new one, and
Speaker 2: the new queries start flowing into this new table. And
Speaker 2: you can do this as long as you want. It's
Speaker 2: entirely non blocking, but it has to be in a
Speaker 2: process that exists entirely outside of like the deployment ZECH.
Speaker 1: Yeah, and that could have its own issues if you
Speaker 1: have you know, thousands of requests per second coming in.
Speaker 1: So yeah, definitely not a fun problem to solve. And
Speaker 1: it's also I guess good to know what kind of
Speaker 1: migration or really what kind of SEQL functions will cause
Speaker 1: a table lock. So adding an index or adding a
Speaker 1: column and stuff can your table. So being aware of
Speaker 1: what actually is going to lock the table is really
Speaker 1: good information to know.
Speaker 2: Some of them seem obvious, like I think if you're
Speaker 2: dropping a column or adding a column, that could potentially lock,
Speaker 2: But some of them are not. Like if you changed
Speaker 2: a VarChar from like a VarChar one hundred to var
Speaker 2: ar chart two hundred and you're just increasing it, does
Speaker 2: that lock? Maybe? I actually don't know off the top
Speaker 2: of my head. What if you change the character set,
Speaker 2: what if you changed the coalition? I don't know.
Speaker 3: Is this on my sequel or post ris.
Speaker 2: This was in We use Percona, which is just an
Speaker 2: offshoot of my sequel, so it'll also be different for
Speaker 2: between databases. So PROCONA might have different decisions.
Speaker 3: Shout out to the ConA guys. I've done some works
Speaker 3: in a place where we had some Pocona consultancy. They
Speaker 3: were really good, really delivered.
Speaker 1: So that kind of covers the database and scheme a
Speaker 1: side of things. To step away from the code you
Speaker 1: had mentioned about onboarding people with a larger client base.
Speaker 1: What does that process look like for you guys, And
Speaker 1: how do you really bring a junior or mid developer
Speaker 1: into the company and have them productive quickly.
Speaker 2: Yeah, so a lot of this comes from tooling and education. Right,
Speaker 2: there's as like senior developers or people who have just
Speaker 2: different experience from different places. We've accumulated huge amounts of
Speaker 2: knowledge and it's kind of all tribal, and I think
Speaker 2: the if you join a company that doesn't have a
Speaker 2: great strategy, a lot of the strategies for sharing that
Speaker 2: knowledge is like just work together, go submit pull requests
Speaker 2: and have them code review and learn from the code review.
Speaker 2: And I think that's okay, you can learn that way,
Speaker 2: But there are better ways to push information to people.
Speaker 2: And this is a concept about like just in time education.
Speaker 2: So one of the an interesting example of this can
Speaker 2: be through the linters. So I did to talk about
Speaker 2: this as well for the twenty twenty Couch edition of
Speaker 2: Rails comp called Communicating with Cops that focused on using
Speaker 2: rubocop as a mech isn't to provide education. Did a
Speaker 2: little bit of deep dive into how ubi cop works
Speaker 2: and how to build your own custom camp. But one
Speaker 2: of the things that we approach with that CLEO is
Speaker 2: as people make mistakes and learn about bad patterns, we
Speaker 2: try to codify those patterns so that it's it doesn't
Speaker 2: happen again, but people get education about it right as
Speaker 2: it happens. A good example of this that is super
Speaker 2: trivialent doesn't often bite people until like there's just an
Speaker 2: unexpected case would be maybe the Rail's convention of naming files.
Speaker 2: We've seen cases where people maybe make like a user's model,
Speaker 2: but then make a typo in like the spec. So
Speaker 2: rather than call them like user, spec called it users
Speaker 2: and it's plural or something along those lines, And you
Speaker 2: know this is like the spec is still run, but
Speaker 2: there might be some tooling that we expect to adhere
Speaker 2: to the Rails convention and it doesn't quite line up.
Speaker 2: So you can have a linter that basically checks the
Speaker 2: name of the files and the name of the classes
Speaker 2: and make sure that they're in line, and if not,
Speaker 2: alert people and do that as part of their editor
Speaker 2: or do that as part of them committing code. And
Speaker 2: they get warnings and they get education as they're writing code.
Speaker 2: So they just wrote something, they save the file, they
Speaker 2: get a little warning popped up being like, hey, you
Speaker 2: may have made a type out here. And this goes
Speaker 2: even too as far as behavior. If we know that
Speaker 2: there exists bad patterns, so for instance, making an HTTP
Speaker 2: call inside of a transaction, which we know is going
Speaker 2: to be potentially bad, we can actually automatically prevent that
Speaker 2: as soon as that starts happening, as soon as we're
Speaker 2: able to detect it. So it might be in a test,
Speaker 2: might be as part of a winter. We provide that
Speaker 2: education right back to the developer so that they understand
Speaker 2: what they did wrong and the avenues of what they
Speaker 2: need to do to fix it. So now when a
Speaker 2: junior developer enters the company, they can actually just feel
Speaker 2: free to start writing code, and write even code in
Speaker 2: kind of a way that maybe breaks some patterns, and
Speaker 2: a lot of time they're going to start getting education
Speaker 2: right away, and then we can do all of the
Speaker 2: usual things as well. As pull requests come in, we
Speaker 2: can review them and provide more education that way. And
Speaker 2: if we find constant patterns of every junior developer we
Speaker 2: come in makes the same mistake, let's codify that so
Speaker 2: that they get the feedback immediately.
Speaker 1: Yeah, that's kind of one of my pet peeves. I
Speaker 1: guess you could say with linting is that if a
Speaker 1: particular project has a set of practices it likes to follow,
Speaker 1: maybe it is no more than one hundred characters on online,
Speaker 1: that kind of feedback should never happen in a code review.
Speaker 1: That if you have those kind of expectations, then they
Speaker 1: need to be known expectations via a linter, whether it's
Speaker 1: Rubacopper standard RB, and it should never be an unknown
Speaker 1: exception to our unknown expectation to the developer. So I'm
Speaker 1: definitely on board with that, And that's something that I've
Speaker 1: had to fight and struggle with, is going through code
Speaker 1: reviews and having everything kind of nitpicked, because one, it
Speaker 1: decreases the morale of the developer if every pull request
Speaker 1: they're making it's just getting bombarded with styling quirks or
Speaker 1: requests to change. So I could definitely agree with that point.
Speaker 1: And I think that every project should adopt some kind
Speaker 1: of linter if there are expectations of what they're doing.
Speaker 1: Even if you bring in rubocop, you disable everything by
Speaker 1: default and then you just start adding in or allowing
Speaker 1: which exceptions your team follows on that particular project.
Speaker 2: Yeah. Absolutely, And I think there's even one step farther
Speaker 2: of a lot of linters can do auto correcting. So
Speaker 2: if you you know, if you care about having on
Speaker 2: one line space between methods, don't even have rubo cop
Speaker 2: or a linter warned about that. Just auto fix it.
Speaker 2: Like that's something that developer just doesn't need to worry about.
Speaker 2: And you know, it also removes a lot of this
Speaker 2: argument over like should I use double quotes? Should I
Speaker 2: use single quotes? If it just auto medically fixed and
Speaker 2: developer can write whatever that they want, that's fine. But
Speaker 2: I've also run into issues of having pull requests being
Speaker 2: bombarded by style and it really distracts from the code
Speaker 2: review about the behavior.
Speaker 1: Yeah. Absolutely, although you do have to be careful about
Speaker 1: the auto correction. I remember one time in my earlier
Speaker 1: days of development, when Ruby mind came out, I tried
Speaker 1: out ruby Mine's code refactoring thing. I forget what they
Speaker 1: call it, but I had some really poorly written classes
Speaker 1: and it just absolutely broke everything. Like, I have no
Speaker 1: idea how that happened, but things just were not working
Speaker 1: the way they were before, and I had to pull
Speaker 1: that merge back out because you know, of course, as
Speaker 1: a early developer, I didn't have any tests on the application,
Speaker 1: so I didn't really notice that things were broken until
Speaker 1: they got deployed.
Speaker 2: Yeah. Yeah, I did definitely need to be careful there.
Speaker 1: So you also previously mentioned about so not necessarily on
Speaker 1: boarding developers, but having a lot of developers work on
Speaker 1: the project. So what point do you go from a
Speaker 1: small shop to a large shop where you have to
Speaker 1: start putting different kinds of practices in place? And what
Speaker 1: are those kind of practices when you're dealing with a
Speaker 1: lot of developers on a single code base.
Speaker 2: So I actually it's not clear where that point exists.
Speaker 2: I think it's probably going to be different for every organization,
Speaker 2: and probably different for exactly the work that you're running into.
Speaker 2: I think the thing is to be listen to the
Speaker 2: pain points of the developers. So if you notice that
Speaker 2: there are you know, there's pieces of friction that occur
Speaker 2: between developers, like that's the point where maybe there's actually
Speaker 2: some tools that need to be built to make this easier.
Speaker 2: So one thing that I think comes up really quickly
Speaker 2: in organizations is often the concept of like a testing server.
Speaker 2: So you've got your developers environment, you've got your your
Speaker 2: maybe your CI but maybe you want like a production
Speaker 2: like environment for things, and so you have a staging serve.
Speaker 2: You know, when there's five developers, it's really just coordinate
Speaker 2: and be like, oh, staging is mine now, I'm going
Speaker 2: to test something. When it's done, I will hand it
Speaker 2: off and maybe reset it back to whatever the master
Speaker 2: branch and let people work that way. But that really
Speaker 2: falls apart when you have one hundred developers. How do
Speaker 2: you coordinate one server where everyone is trying to test something.
Speaker 2: If you have one hundred developers fighting for that resource,
Speaker 2: you can kind of budget a little bit by maybe
Speaker 2: having a fixed number, and you know, you round robbing
Speaker 2: them out, but again, at some point that's going to
Speaker 2: break down. So if you think about, like, what's the
Speaker 2: problem here is that every developer wants to potentially test
Speaker 2: something on an asynchronous schedule, maybe it actually makes sense
Speaker 2: to build some tooling so that you can spin up
Speaker 2: a like staging servers on like Amazon Easy two or
Speaker 2: on Google on Demand and just route them there. And
Speaker 2: so that's something that we ended up having to do
Speaker 2: really early of building our own toolings so that we
Speaker 2: can we call them beta environments where we can have
Speaker 2: arbitrary number of them. Someone spent the effort to basically say,
Speaker 2: like this branch on GitHub, I want a clone of
Speaker 2: the site on Amazon, and within like ten minutes, you've
Speaker 2: got a domain that points to it. You've got the
Speaker 2: full stack, you can you have full control, you can
Speaker 2: do whatever you want, you can break it, and it
Speaker 2: gives developers a lot of autonomy to test things that
Speaker 2: they want, and you know, removes a lot of this, Oh,
Speaker 2: let's deploy it and see what happens. You have a
Speaker 2: full environment that you have full control over, Go test it,
Speaker 2: go see it with as much data as you want,
Speaker 2: and then see what happens. Another example kind of along
Speaker 2: those things is like deployments. Do you have a handful
Speaker 2: of senior developers who can deploy or do you deploy
Speaker 2: on like a every Monday you do a big deployment
Speaker 2: that's going to start really breaking down when you have
Speaker 2: a lot of developers. You know, at CLEO, everyone has
Speaker 2: the ability to deploy, everyone has the ability to merge code.
Speaker 2: So we give the power to the developers and now
Speaker 2: you know, a junior developer can come in, write a
Speaker 2: fix to a read me, merge the code, deploy it
Speaker 2: without having to really bother people outside of getting a
Speaker 2: code review. And know, now we're deploying code probably upwards
Speaker 2: of thirty ish times a day, and that number is
Speaker 2: just only going to go up. And so as we're
Speaker 2: running into these issues, we are just looking at what
Speaker 2: can we do to build tooling so that it's no
Speaker 2: longer frustrating for developers. And the important part of this
Speaker 2: is developers need to voice things, and you know, managers
Speaker 2: and companies need to listen. If we're wasting five hours
Speaker 2: a week per developer on this one thing that's frustrating,
Speaker 2: like build tooling around it.
Speaker 1: Yeah, that's one of the things that I did just
Speaker 1: for my own hobby project and just continual learning, is
Speaker 1: that a self hosted git lab instance and I set
Speaker 1: up a Kubernet server which will automatically create the infrastructure
Speaker 1: for the application that got pushed, so it always happens
Speaker 1: on any kind of development or master branch push and
Speaker 1: then also on each commit up to the repository and
Speaker 1: they'll spin up an entire infrastructure within Kubernetes with the
Speaker 1: FQDN that that feature can then be tested. So it
Speaker 1: works on smaller applications. I don't know how it would
Speaker 1: work on applications that consume thirty gigs of RAM of resources,
Speaker 1: but I think on smaller applications that kind of thing
Speaker 1: can really save you from having to have dedicated test
Speaker 1: servers that shared by several people.
Speaker 3: When are you going to do an episode on that, Dave?
Speaker 1: I do have a Jefre Ruby episode on Kubernetes, which
Speaker 1: that's where I got the inspiration from. On that episode,
Speaker 1: I just didn't tied into the CICD portion.
Speaker 3: I got a I got a question for you, Kyle.
Speaker 3: It sounds like you've got to You've got a lot
Speaker 3: of data if you're running thirty minute migrations, and you've
Speaker 3: got a lot of developers, and you've got a good testing,
Speaker 3: good infrastructure. What I what I've found is a lot
Speaker 3: of kind of real memorable problems I've had is where
Speaker 3: you get something running and it feels like it's going
Speaker 3: to be fine, but then it gets deployed to the
Speaker 3: master database and that's the point at which there's some
Speaker 3: bad data in there. There's something in there from ages ago,
Speaker 3: from a previous version, and it absolutely sinks you. And
Speaker 3: these days, whenever I possibly can, I just pulled the
Speaker 3: entire production database out and test against that. Do you
Speaker 3: do that or is your database just so huge, kind
Speaker 3: of throwed around. You can't do that, especially with a
Speaker 3: lot of her developers.
Speaker 2: It used to be something that we did. We used
Speaker 2: to have We used to call it the snapshot, and
Speaker 2: you could point environments at the snapshot and run test
Speaker 2: queries on it, but we actually do it did hit
Speaker 2: a size where the time it took to set up
Speaker 2: the snapshot every day was taking longer than it would
Speaker 2: take to actually back it up. So it was just
Speaker 2: starting to become unfeasible for us. And we're also dealing
Speaker 2: with sensitive data and we don't necessarily want to give
Speaker 2: free access to all of that data for our our clients,
Speaker 2: so we instead try to invest in a little bit
Speaker 2: of tooling. We definitely still have issues where everything looks
Speaker 2: good in development, everything looks good in like data or
Speaker 2: test and we deployed to production, something is wrong. So
Speaker 2: we think about what can we do to make that better?
Speaker 2: And so we you know, if it's about a lack
Speaker 2: of index on like a database query or something like that,
Speaker 2: we can try to check that ahead of time and
Speaker 2: build some tooling and alert people when something goes wrong.
Speaker 2: But also in production we can be say like, hey,
Speaker 2: this query took thirty minutes, that's unacceptable, this career took
Speaker 2: five minutes and return that information as like an exception
Speaker 2: to the developers that they need to fix, but without
Speaker 2: interrupting the actual request behavior. And if things go really south,
Speaker 2: just roll it back, like we don't really have. It's
Speaker 2: not a blame if someone deploys thing and goes south
Speaker 2: and they quickly roll it back. We just try to
Speaker 2: take that as a learning opportunity. And how can we
Speaker 2: take that learning opportunity and share it to everybody so
Speaker 2: that everyone learns from it. Then answer your question.
Speaker 3: Yeah, I mean you must be dealing with a lot
Speaker 3: of data, and I've worked with you call it hipA
Speaker 3: data in the States where it's kind of confidential data,
Speaker 3: and that hugely complicates testing data chranswers because you have
Speaker 3: to have to either heavily anonymize or write your own
Speaker 3: tools kind of replicate a few one hundred thousand medical records.
Speaker 2: Yeah. All we can also do is I mentioned earlier
Speaker 2: that we could talk. We have these data environments that
Speaker 2: we can spin up. You just use like a sequel
Speaker 2: dump to store data in there. And although this isn't
Speaker 2: necessarily production data, developers have full control over what that
Speaker 2: data looks like. And so you know, if we wanted
Speaker 2: to see what happens if there is tens of thousands
Speaker 2: of something in a table or more, we can just
Speaker 2: build like little scripts that can feed this seed that
Speaker 2: database and then test it outside of production. It's not
Speaker 2: perfect because it doesn't always match the same shape as production,
Speaker 2: but you can. It's an iterative process, and that information
Speaker 2: gets codified, so you can keep adding to the seeds
Speaker 2: in those manner so that it becomes a better and
Speaker 2: better representation as.
Speaker 1: We go forward. Yeah, so kind of back to the
Speaker 1: technical debt. I have a unfortunate story of something that
Speaker 1: I inherited one time where I think metaprogramming is awesome
Speaker 1: and can do a lot of really cool things and
Speaker 1: can really get you out of a bind in certain situations,
Speaker 1: but then it can also be overly abused. And I
Speaker 1: was searching for a function that was not working properly
Speaker 1: within Ruby, and I couldn't find it in the code
Speaker 1: base at all. So I thought, okay, well, surely that
Speaker 1: this is in the gym or something. So I started
Speaker 1: looking at all the gems that's included into this Rails application,
Speaker 1: started tearing apart the gems, opening them to search for
Speaker 1: this function. Still couldn't find it. Turns out they are
Speaker 1: doing a classy val on something that's pulled from the database.
Speaker 1: So they actually stored Ruby functions as column or data
Speaker 1: within a column on the database, and that's what was
Speaker 1: getting executed. That's where the function was defined. So to me,
Speaker 1: that's a what's that?
Speaker 3: What's wrong with that?
Speaker 1: Yeah, so you know, other than you could not possibly
Speaker 1: even test that bit of code any with any kind
Speaker 1: of reason. But it was a nightmare. So just a
Speaker 1: warning to when you think that you're doing something really
Speaker 1: cool and elegant that's avoiding code duplication or whatever. I
Speaker 1: would much rather have code duplication all across my application
Speaker 1: than having that level of obfuscation where you're never going
Speaker 1: to be able to even remotely troubleshoot it.
Speaker 2: Yeah, metaprogramming is a like it's actually one of the
Speaker 2: best lengths of Ruby. You can do so much with it,
Speaker 2: but it's on you once you have it. It's the
Speaker 2: hammer and everything is a nail, and you want to
Speaker 2: use it. And that's that's often a trap that new
Speaker 2: developers when they learn about metaprogramming, they really want to
Speaker 2: go into. I think a good lesson to come out
Speaker 2: of that story is that if you think about code,
Speaker 2: it's written once but read countless times, and so if
Speaker 2: you can take the little things to optimize the code
Speaker 2: for the reader, that is much better than sacrificing readability
Speaker 2: to optimize for the writer. So if it takes you
Speaker 2: an extra thirty minutes to write a whole bunch of
Speaker 2: cookie cutter methods, but now those methods are in place
Speaker 2: and they're static and it's easy to read and reason
Speaker 2: about end test, that is well worth that thirty minutes,
Speaker 2: because you're going to lose more than that reading that
Speaker 2: piece of code in the future.
Speaker 1: Yeah. Absolutely, And it could even be taken into something
Speaker 1: like private methods where if you have a class which
Speaker 1: has a bunch of methods, start sorting them out which
Speaker 1: ones are private methods so they do not need to
Speaker 1: be accessible to the consumer, because I've had situations where
Speaker 1: I've worked on a class that grew over a thousand
Speaker 1: lines and there were hundreds of methods in there, and
Speaker 1: I had no idea which ones were publicly accessible, that
Speaker 1: were truly supposed to be publicly accessible, and which ones
Speaker 1: were really meant to be private. So not having that
Speaker 1: level of abstraction, so to speak, you lose a lot
Speaker 1: of visibility in how important is this class to the consumer.
Speaker 2: Yeah. Absolutely, anything that you can do to make those
Speaker 2: kind of classes easier to understand and read for a
Speaker 2: new person is great. And also just backing up a
Speaker 2: little bit to your example, this is also an instance
Speaker 2: where metaprogramming bit you, but metaprogramming is also interesting that
Speaker 2: it could save you because you can also ask Ruby
Speaker 2: about Ruby. So if anyone didn't know what this is
Speaker 2: a attack that I use all the time for debuton
Speaker 2: pieces of code that I've never been familiar with, you
Speaker 2: can If you can have access to a console, you
Speaker 2: can ask Ruby what methods are available with like a
Speaker 2: dot methods call. You can also get access to the
Speaker 2: method itself and then ask it like, what is its source,
Speaker 2: where does it live where? That can make life easier
Speaker 2: to track down methods that may be dynamic or created
Speaker 2: by gems.
Speaker 3: I recently learned how to use the LS command in Prey,
Speaker 3: and now I just I just live out of the
Speaker 3: LS pri command. The Ruby API traffic's drop off considerably.
Speaker 3: I find I find the dot methods to be quite noisy.
Speaker 3: This is very the bose if you're kind of trying
Speaker 3: to pick out which command it is. And I really
Speaker 3: like the pre LS command.
Speaker 4: Yeah, I mean you can do to make that less
Speaker 4: noisy is take like object dot new and subtract the
Speaker 4: methods out of that and sort it and all that
Speaker 4: sort of stuff, and you can do it all on
Speaker 4: a one liner because we're in But yeah, I'll ask
Speaker 4: is another great option.
Speaker 3: It's my documentation suffered for it. I must admit. Now
Speaker 3: my attitude is just I can just arlest the class
Speaker 3: and see what's going on. Man.
Speaker 2: I think that's another example of someone making some tooling
Speaker 2: that you know, makes something that. Yeah, if you knew
Speaker 2: to call dot methods and subtract object dot new dot
Speaker 2: methods or object dot methods, it's great. But now it's
Speaker 2: two characters and it's nice and easy, and it's much
Speaker 2: more approachable, and then you can have access to things
Speaker 2: that you may not knew existed.
Speaker 3: Can I ask you about can we turn back the
Speaker 3: clock and ask you about Rail's zero?
Speaker 2: Oh, it's been a long long time since I've worked
Speaker 2: on rail zero. I can try to answer questions, but.
Speaker 3: So it sounds like you've been on a bit of
Speaker 3: a journey with scaling things up. What did you do
Speaker 3: before rail zero?
Speaker 2: Oh? I Actually most of my career has been working
Speaker 2: with rails. So before rail zero, I was working at
Speaker 2: like an enterprise Java shop that I don't remember a
Speaker 2: lot of details of it anymore. It's kind of too
Speaker 2: far in the past. But I think I've been working
Speaker 2: with rails now for eleven years. I think, so it's
Speaker 2: been just a long time just rails. I don't remember
Speaker 2: a lot of the pre rails world. To be honest,
Speaker 2: that is.
Speaker 3: The correct answer. There is no other system. I ask
Speaker 3: because we were talking about the N plus one queries,
Speaker 3: and my complaint is that rails makes it too easy
Speaker 3: to do N plus one queries because if you just
Speaker 3: kind of thought of all the guides, that's what you get.
Speaker 3: If you kind of do a dot lder each. Then
Speaker 3: you're going to be there for a while and you
Speaker 3: start noticing that when you start getting into a few
Speaker 3: thousand objects. So you can be sitting there prototyping something
Speaker 3: and think this is great, and then when people start
Speaker 3: using it, you drop it in. That's when you start
Speaker 3: hitting these gotchas. But I think people forget what the
Speaker 3: battle days were before you had the rails tooling out
Speaker 3: of time it took when you had to write your
Speaker 3: own queries. It's really quite significant. And they mentioned Enterprise
Speaker 3: Java that was not a whole lot of object relation
Speaker 3: mapping going on in that, so that it is a
Speaker 3: double edged sword when you're operating at the scale you do,
Speaker 3: what are the parts of rails that start to bite.
Speaker 2: We've definitely been bitten by how easy it's been to
Speaker 2: make M plus one queries in the past. I think
Speaker 2: pretty much any rail shop is going to be doing it.
Speaker 2: Rails offers tooling to help with that, but the tooling
Speaker 2: still requires a lot of effort. You have to kind
Speaker 2: of know what N plus one query you're introducing and
Speaker 2: fix it. So though that's where you can build some
Speaker 2: more tooling. There exists a gem that we built a
Speaker 2: jip preloader. There's also another community gem called a Goldie
Speaker 2: loader that removes stuff like M plus one queries, and
Speaker 2: those are ways to like basically eliminate those kind of problems.
Speaker 2: Some other things that kind of come off on Rails
Speaker 2: as we are building is like discoverability of templates. So
Speaker 2: I think you're one of the previous episodes of Ruby
Speaker 2: Ropes was talking about this, but as as it scales
Speaker 2: up like rails, EERB makes it really easy to render
Speaker 2: partials all over the place, but it's really hard to understand,
Speaker 2: like if you're looking at a page, where are those
Speaker 2: partials actually coming from? And how can you dig back
Speaker 2: into them? So we've like that's a challenging thing with
Speaker 2: rails as well. There's also some things with the community
Speaker 2: for things like paging that can be problematic at scale.
Speaker 2: If you look at what some of the basic gems
Speaker 2: that offer, it often comes down to a limit offset,
Speaker 2: which is also really fine on small data sets, but
Speaker 2: as you get too data sets that are really really
Speaker 2: large and you're going to page really deep into them,
Speaker 2: it actually starts really falling apart and breaking down and
Speaker 2: things that you might not know until you actually just
Speaker 2: hit that scale. I think the some of the RAILS
Speaker 2: conventions also starts becoming a little bit problematic, and you
Speaker 2: see a little bit of discussion about this. You know,
Speaker 2: Rails at one point said throw all the logic into
Speaker 2: the controller, and then eventually the controllers became skinny and
Speaker 2: all the models became really fat. And I'm sure everyone
Speaker 2: has that god object that exists in their project, the
Speaker 2: user object or the account object that is five thousand
Speaker 2: lines and really difficult to reason about. And people are
Speaker 2: offering opinions of having like service classes or various different
Speaker 2: patterns to try to combat that. But we're still trying
Speaker 2: to unpack some of the things that you started to
Speaker 2: RAILS projects with.
Speaker 4: One question on that as far as how you've seen
Speaker 4: and the progression of the companies you've worked at, have
Speaker 4: documentation right, Like, on the one hand we've just talked about,
Speaker 4: you can use cops, you can use linters and say
Speaker 4: go out and try things, break things, autocorrect things, experiment basically,
Speaker 4: then there's self documentation making sure you're writing good method names,
Speaker 4: good class names that are intuitive, and then there's inline documentation,
Speaker 4: and then there's high level documentation of hey, we're using
Speaker 4: this set some conventions and everything else. This is a
Speaker 4: big question, but what what do you think is the
Speaker 4: right thing to put in each of those buckets in
Speaker 4: order to make an intuitive project that scales across you know,
Speaker 4: more than twenty developers up to one hundred developers.
Speaker 2: Yeah, and you know, here's a little bit of like
Speaker 2: my kind of thoughts from it. But I'm not going
Speaker 2: to say, like my thoughts here are perfect. I think
Speaker 2: everyone's mile edge will vary because documentation is a tricky thing.
Speaker 2: So when you get to if you're getting to like
Speaker 2: gotcha's like if you ever tell someone like, oh, if
Speaker 2: you see this pattern, don't do it like this is
Speaker 2: like if you have code reviews that like, oh, I've
Speaker 2: been bitten by this before, that should be something that
Speaker 2: falls into like the linting or the like the just
Speaker 2: and time education where you try to codify that. If
Speaker 2: you see people that have inline comments and code that says,
Speaker 2: you know, like this next few lines are going to
Speaker 2: iterate over something and do these operations, that's probably an
Speaker 2: indication that their code is not written well to describe it,
Speaker 2: and that comment is not super valuable, so that actually
Speaker 2: it might be something like that comment shouldn't exist, and
Speaker 2: instead we should maybe extract a method that describes it
Speaker 2: better and kind of move in the direction of code
Speaker 2: describing itself. When you are implementing something that's specifically tied
Speaker 2: to code, it should probably exist at the code level.
Speaker 2: So if you are if you have like a module
Speaker 2: that you want things to include, and someone developers need
Speaker 2: to implement certain methods in there, maybe the module should
Speaker 2: define those methods and raise like a not implemented error
Speaker 2: that have a very clear this is what this method
Speaker 2: should do, this is what it should return. Here are
Speaker 2: some examples, and just link to them in your own codebase.
Speaker 2: And so now when a developer looks at that specific
Speaker 2: piece of code, it's still tied to the codebase. But
Speaker 2: all of that's, you know, at the code based level.
Speaker 2: There still needs to be something at like a higher
Speaker 2: level that's like a read me in the documentation or
Speaker 2: in something else entirely, So we have stuff that exists
Speaker 2: and read me that's kind of more about like process,
Speaker 2: but process is specifically related to our code based So
Speaker 2: a good example of this would be how do you
Speaker 2: do this these asynchronous migrations? So like this isn't really
Speaker 2: super tied to code, because you might make a migration,
Speaker 2: but then what's the process for getting that live? So
Speaker 2: we have a like a step by step guide to
Speaker 2: be for ra clio. If you want to do a migration,
Speaker 2: here are the steps that you need to take, and
Speaker 2: as much as we can, we just link back to
Speaker 2: code rather than re implement the code. But we'll also
Speaker 2: just describe things in English and offer templates there and
Speaker 2: then we go one level higher to things that exist
Speaker 2: more at like a process level for the organization. So
Speaker 2: for that we use a tool called Confluence. There's lots
Speaker 2: of tools that exist that kind of do similar things,
Speaker 2: but for those that's that's things that exist outside of
Speaker 2: the code based So if an incident happened, how do
Speaker 2: you do a post or would cause analysis on that
Speaker 2: and there'll be documents for that. Or you know, if
Speaker 2: you wanted to propose a new style of a new
Speaker 2: feature that you wanted to get some buy in using
Speaker 2: some new architecture, just wanted to make sure that the
Speaker 2: approach is correct, you can do like a design doc
Speaker 2: in this confluence and get people kind of bought in
Speaker 2: well before you've actually written the code. But once the
Speaker 2: code is written, that document is less relevant.
Speaker 4: Absolutely. I was kind of going from the standpoint of,
Speaker 4: like we were talking about bringing a new developer in
Speaker 4: and getting them used to the whole environment, and you've
Speaker 4: definitely tackled some of that in terms of, you know,
Speaker 4: here's the process migration example there. What about just getting
Speaker 4: them used to the entire structure of your application where
Speaker 4: certain logics live, certain design paradigms that you've talked about.
Speaker 4: Some of those can be encapsulated in lnters, but some
Speaker 4: of them are larger than winters, And so is that
Speaker 4: when you're doing the specific guide for walking them through
Speaker 4: that process.
Speaker 2: Yeah, so then there's definite things that lenders aren't going
Speaker 2: to be able to do, Like linder won't be able
Speaker 2: to tell whether this thing should be a model or
Speaker 2: a service class or something. Right, it's not really going
Speaker 2: to be able to it doesn't understand the business logic
Speaker 2: of it. So for things like that that we kind
Speaker 2: of have to rely on like little handbooks of being
Speaker 2: Like here, like we've code fight, our style guide. We
Speaker 2: try to make sure that we keep that up to date.
Speaker 2: There are some things that we still teach through kind
Speaker 2: of tribal knowledge and code reviews, like if some smits
Speaker 2: a pull request and we notice it, we'll still correct
Speaker 2: it there and we'll do a lot of pairing, so
Speaker 2: we'll get developers up to speed by working with people
Speaker 2: as supposed to just going off on their own. But
Speaker 2: I think this is just a learning process. Like we
Speaker 2: I don't think we are perfect at getting developers onboarded,
Speaker 2: and I don't think anyone is. And I think that's
Speaker 2: the important distinction that you just it's an iterative process.
Speaker 2: Is if you if you bring in three developers and
Speaker 2: they all have the same issue, that's probably when you
Speaker 2: might need to introduce some new documentation and be like, hey,
Speaker 2: here's our new developer handbook. You might want to read it.
Speaker 4: And then that absolutely and you've been on top of that.
Speaker 4: You have personalities too, and you know certain people gravitate
Speaker 4: towards certain things. How what's your methods to when you
Speaker 4: have what I would consider external documentation, whether that's living
Speaker 4: and or read me. It's not in a Ruby file
Speaker 4: or an HTML file or something like that. How do
Speaker 4: you guys have any triggers in order to Hey, if
Speaker 4: something happens over here and we decide on a new paradigm,
Speaker 4: make sure you go update that guide documentation or is
Speaker 4: it oh, just like we brought a new person in
Speaker 4: and we've got this new convention that's not documented. Oh geez,
Speaker 4: we got to go update that documentation. And it's kind
Speaker 4: of a only when you discover it type of issue.
Speaker 2: So I think the answer is both. I definitely think
Speaker 2: we still have places where our documentation drifts and then
Speaker 2: somebody notices and we're like, oh shit, we got we
Speaker 2: gotta fix that. But we also do leverage tools like
Speaker 2: danger danger GSS, like GitHub where it can look at
Speaker 2: code and it's not necessarily like a linter of basically
Speaker 2: saying like hey, this is bad, but it can make
Speaker 2: a comment of being like, hey, you're doing something maybe
Speaker 2: this is related to this this link over here, and
Speaker 2: direct developers or whoever's reviewing to go take a look
Speaker 2: at the documentation. Maybe there's no changes that require there.
Speaker 2: And we definitely need to be careful about how much
Speaker 2: noise we generate. But you know, if in the case
Speaker 2: of like a migration, if a developer writes some on
Speaker 2: migration and then submits it, we could basically say, hey,
Speaker 2: did you add a new file to like the dB
Speaker 2: migrate file. If so, like make sure you're following the
Speaker 2: gut steps in here and make sure that it aligns
Speaker 2: and kind of point them back at the documentation, both
Speaker 2: for the writer of the pull request but the reader
Speaker 2: and then kind of helps make sure that things stay
Speaker 2: in sync. Not a perfect process. I think we're just
Speaker 2: we're slowly getting better at making sure that documentation stays
Speaker 2: up to date.
Speaker 4: Yeah, that's always the painful part. Those are great insights.
Speaker 3: What do you think about DHHH? Guy, it's a Weirdosney
Speaker 3: I was, I was. It did denounce that just me. No,
Speaker 3: I love DHH. She did a book of quite a
Speaker 3: few years ago Could Rework, which was prophetic really in
Speaker 3: the current situation about working from home. He did a
Speaker 3: Rails comp you know, I think it was a couple
Speaker 3: of years ago where he said that at base Camp
Speaker 3: they have never had a DBA, so they've never employed
Speaker 3: a person whose job it was to administer the database.
Speaker 3: This is something which Rails has just just magically scaled
Speaker 3: up and the database is scaled up. Do you are
Speaker 3: you in the same situation? Have you never employed a
Speaker 3: DBA for your very large Rails database?
Speaker 2: Yeah, actually we are in the same situation. I believe
Speaker 2: we I think we were going to hire a DBA
Speaker 2: this year prior to the pandemic, and then I think
Speaker 2: there were some complications. But prior to that, the company
Speaker 2: has been operating for over eleven years, and I think
Speaker 2: now no DBA, we definitely have some DevOps that are
Speaker 2: a little bit like focused on making sure that the
Speaker 2: database is running and making sure that you know, we've
Speaker 2: got replications set up and proper statistics. But we kind
Speaker 2: of put the onus on everyone, like you don't have
Speaker 2: one person who is the guru of SQL, you have everyone,
Speaker 2: and so everyone tries to teach everyone these things and
Speaker 2: we try to do our best to share that knowledge
Speaker 2: where we can to make everyone as experts as we can.
Speaker 2: So we've managed to go, you know, eleven years with
Speaker 2: no DBA, and I think we're only getting to wanting
Speaker 2: one now because we're trying to do like really customized
Speaker 2: processes of how do we you know, this online schema
Speaker 2: migration stuff, how do we make that completely automated, which
Speaker 2: is actually going to be a completely distinct system to
Speaker 2: the rail system, because we're going to want to apply
Speaker 2: it to any of our projects, or maybe some gotchaes
Speaker 2: between like upgrading my sequel there's probably some things that
Speaker 2: they might actually have really good insight into. But I
Speaker 2: think our general approach is, even in that situation, we're
Speaker 2: going to have one DBA and hundreds of developers, and
Speaker 2: we want to make sure that, you know, they may
Speaker 2: have knowledge and might be useful for talking through things
Speaker 2: and sharing things, but the work it's going to still
Speaker 2: fall in with the developers, and you know, I mean
Speaker 2: to make sure that everyone is learning as much as
Speaker 2: they can and not just blindly hoping that the DBA
Speaker 2: is going to handle it.
Speaker 3: Yeah, I mean it's the way. The way if DH
Speaker 3: presented it, it was kind of this is this is
Speaker 3: a necessary evil mind was to have a database specialist
Speaker 3: this instead who rails enables developers to kind of handle
Speaker 3: this themselves and not just kind of blame the database
Speaker 3: man or woman when the when the thing goes wrong.
Speaker 3: Surely as a company gets bigger, you have more specialized
Speaker 3: roles and not less specialized roles.
Speaker 2: Yeah, I would agree, and I think there are more
Speaker 2: specialized roles, but I think there are skills that apply
Speaker 2: to everyone. So you know, as the company grows, you
Speaker 2: may have more specialized roles that have more specific knowledge.
Speaker 2: But I think probably with that specific knowledge comes the
Speaker 2: responsibility that they are not gatekeepers of that knowledge, right
Speaker 2: they They may be experts and they're maybe building content,
Speaker 2: but I would say part of their job is to
Speaker 2: make sure that it's that content is consumable by everyone.
Speaker 2: And you know, if they're answering the same questions over
Speaker 2: and over and over, they're not doing their job to
Speaker 2: educate people on how to self serve and do it themselves.
Speaker 2: And that's how we learn and grow as a community
Speaker 2: and get better is just by sharing this knowledge.
Speaker 3: It's a it's a really quite an interesting situation. I
Speaker 3: don't know what it means for the DBAs, but I
Speaker 3: think there's there's definitely more database work out there. But
Speaker 3: I think because RAILS just makes it so easy to
Speaker 3: work with databases at scale, that you kind of tend
Speaker 3: to hit hit that stage much much later on.
Speaker 2: Yeah, I agree, you don't necessarily have to have everyone
Speaker 2: customly building SQL like Active record does a pretty good
Speaker 2: job of being an RM that let's developers just do
Speaker 2: the things they need to do. And you know, there's
Speaker 2: data notifications available to easily add tooling that you don't
Speaker 2: need the DBA for. But you know, as things grow.
Speaker 2: There's things that RAILS doesn't yet have tooling, and maybe
Speaker 2: that's something that like if you have a DBA who
Speaker 2: is well versed in RAILS, like maybe they can contribute
Speaker 2: back to the framework or at their own gems that
Speaker 2: can help everybody get better at working with databases. And
Speaker 2: you know, it doesn't necessarily invalidate their job, but their
Speaker 2: job becomes more of a knowledge producer and they try
Speaker 2: to share that knowledge and make the community better.
Speaker 4: Yeah, we're in the same boat. We like to push
Speaker 4: that knowledge down as far as possible, but there certainly
Speaker 4: are opportunities when you're deep in the materialized viewsed and
Speaker 4: windowing and postgraphs or something like that, where you're just like,
Speaker 4: I really want to phone a phone, a deba friend.
Speaker 4: And that's the conside I would suppose, Yeah, And.
Speaker 2: I think that's that's like the roles of the specialists,
Speaker 2: the people who have the specialized knowledge, they're probably more consultants.
Speaker 2: And you know, you have someone who's like, I've got
Speaker 2: a really gnarly problem. I don't know what to do. Yeah,
Speaker 2: like get them to like sit down and help with you.
Speaker 2: And that's a big asset that they can help with
Speaker 2: people and you know, if that's a one off, it's
Speaker 2: a one off. But if they do this ten times
Speaker 2: in a week, maybe there's education there, or maybe there's
Speaker 2: two ling. And I think it goes to pretty much
Speaker 2: any role that you ever feel like you're just throwing
Speaker 2: something over the fence. If you push that responsibility also
Speaker 2: to the developers, you can also end up with a
Speaker 2: much higher quality project.
Speaker 4: Kids them how to use includes and avoid some of
Speaker 4: those massive queries and plus one problems.
Speaker 2: Or use some of the gems available and have the
Speaker 2: n plus one queries just automatically avoided for you. You bet.
Speaker 1: Yeah, I've had some include statements which spend fifty lines
Speaker 1: on some projects that inherited. Its insane the kind of
Speaker 1: data that they're trying to return, But yeah, it's crazy
Speaker 1: good advice.
Speaker 2: One also, is anything else.
Speaker 1: That we want to talk about. I know we're getting
Speaker 1: at about that time.
Speaker 2: I'm just going to mention one thing about includes, because
Speaker 2: I think this is a another gotcha of RAILS is
Speaker 2: they don't really teach you what happens with includes and
Speaker 2: includes as actually does two things in the backgrounds. It
Speaker 2: either uses a preload or an eager load, and a
Speaker 2: preload splits it off into a different query entirely, where
Speaker 2: you do something like select star from table where id's
Speaker 2: in this big list. But then there's eger load, which
Speaker 2: tries to smosh it into one big query. This is
Speaker 2: something where Rails always suggest using includes because it'll handle
Speaker 2: that distinction for you. But that distinction actually makes a
Speaker 2: difference at scale, and when you're dealing with large tables,
Speaker 2: eager load is almost always worse significantly, and so it's
Speaker 2: almost all the time you actually want to use preload,
Speaker 2: same interface, but it's just this interesting little goatcha that
Speaker 2: you don't really realize until it starts biting you.
Speaker 4: And you got to remember everything is just a tool,
Speaker 4: and you can either smash your finger with that hammer
Speaker 4: or you can build what you want to build with it.
Speaker 2: Exactly great, Kyle.
Speaker 1: If people want to follow you and some of the
Speaker 1: stuff that you're doing online, where should they go.
Speaker 2: I don't really have a huge online presence. I do
Speaker 2: have a GitHub account, but that's mostly working on like
Speaker 2: either public gems for the company. But what I'm trying
Speaker 2: to do is be a little bit more present in
Speaker 2: the community. So I do have some talks available at
Speaker 2: rails cof and I will like my goal is to
Speaker 2: be pushing out a little bit more written content which
Speaker 2: is available at like the blogs that Cleo provides, so
Speaker 2: I can provide a link for that in the future,
Speaker 2: as well as a link to any of the talks
Speaker 2: that I have. But unfortunately I'm not a super user
Speaker 2: on Twitter, but I can also provide my LinkedIn where
Speaker 2: I sometimes post new introgeration there as well.
Speaker 1: Awesome, Well, I'm going to move us over to some picks. Looke,
Speaker 1: do you want to start us off?
Speaker 3: Yeah, listen, listen to this. Listen to this. Can you
Speaker 3: hear that?
Speaker 2: I can't hear anything that.
Speaker 3: That is the sound of me signing up for Drifting
Speaker 3: Ruby dot com, which is a quite excellent a series
Speaker 3: of rails gusts, including the accident from jQuery to ES
Speaker 3: six episode. I am a notorious jQuery user, almost an
Speaker 3: unrepentant one, but Drifting Ruby has let me see the
Speaker 3: light and I'm a newly reformed character. So my pick
Speaker 3: is Drifting Ruby dot com.
Speaker 1: I must say that's a great pick. So all right, hey, Matt,
Speaker 1: you want to chime in with some picks.
Speaker 4: Well, my pick comes out of this. I'd say that
Speaker 4: danger JS is something that I really want to look into.
Speaker 4: We're significantly investing in see I see infrastructure and deploying
Speaker 4: those branches like you were talking about, Dave, and so
Speaker 4: that looks like a really great way to tie back
Speaker 4: to documentation and check the best practices that can form
Speaker 4: with the rest of the company. And that's my pick
Speaker 4: for today. I'll let you know what I discover awesome.
Speaker 1: I'll jump in with a couple of picks. One is
Speaker 1: from Google. It is a type in security key. Other
Speaker 1: companies have similar products, like the Ubo key. It's a
Speaker 1: USB or a NFC key that will do your authentication
Speaker 1: for you. So actually, I have a couple of these
Speaker 1: arriving in the mail today in preparations for another Drift
Speaker 1: and Ruby episode that I want to do on these things.
Speaker 1: So that should be a pretty interesting one. I don't
Speaker 1: think it's going to have too much popularity because I
Speaker 1: never have one of these keys before later today. And
Speaker 1: the other is I have now in front of me
Speaker 1: a little rack of Raspberry p i eight gigabyte of
Speaker 1: rams that I'm building into a tiny Kubernetes cluster for well,
Speaker 1: just because that can really so. I love raspberry pies
Speaker 1: and they just released their eight gigabyte versions, which actually
Speaker 1: banks it nicer to run some heftier things on it now.
Speaker 1: Still slow, but still a lot of fun. All Right, Kyle,
Speaker 1: do you want to join in with some picks.
Speaker 2: I didn't prepare anything, so I actually don't have anything
Speaker 2: that's off the top of my mind here for things
Speaker 2: to just call out.
Speaker 1: All right, fair enough, Well, it was great talking to you, Kyle,
Speaker 1: and I always like talking about technical debt because I
Speaker 1: am notorious for introducing it.
Speaker 2: I'm always happy to like building tools to fix these
Speaker 2: things so that we can make better.
Speaker 1: All right. Well, that's a wrap for this episode. We
Speaker 1: appreciate you coming and talking with us. So it was
Speaker 1: a lot of fun.
Speaker 2: Yeah, it was wonderful. Thank you, Bye, take care.