[This episode is sponsored by Rackspace. Are you looking for a place to host your latest creation? Want terrific support, high performance all backed by the largest open source cloud? What if you could try it for free? Try out Rackspace at RubyRogues.com/Rackspace and get a $300 credit over six months. That’s $50 per month at RubyRogues.com/Rackspace.]
[This episode is sponsored by Codeship.io. Don’t you wish you could simply deploy your code every time your tests pass? Wouldn’t it be nice if it were tied into a nice continuous integration system? That’s Codeship. They run your code. If all your tests pass, they deploy your code automatically. For fuss-free continuous delivery, check them out at Codeship.io, continuous delivery made simple.]
[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on Ruby developers, providing them with salary and equity upfront. The average Ruby developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. It’s totally free for users. And when you’re hired, they also give you a $2,000 signing bonus as a thank you for using them. But if you use the Ruby Rogues link, you’ll get a $4,000 bonus instead. Finally, if you’re not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/RubyRoguesPodcast.]
[Snap is a hosted CI and continuous delivery that is simple and intuitive. Snap’s deployment pipelines deliver fast feedback and can push healthy builds to multiple environments automatically or on demand. Snap integrates deeply with GitHub and has great support for different languages, data stores, and testing frameworks. Snap deploys your application to cloud services like Heroku, Digital Ocean, AWS, and many more. Try Snap for free. Sign up at SnapCI.com/RubyRogues.]
CHUCK:
Hey everybody and welcome to episode 176 of the Ruby Rogues Podcast. This week on our panel, we have Avdi Grimm.
AVDI:
Hello from Pennsylvania.
CHUCK:
Saron Yitbarek.
SARON:
Hey everybody.
CHUCK:
Pete Hodgson.
PETE:
Hello from the city that knows how.
CHUCK:
I’m Charles Max Wood from DevChat.TV. Before we get started, I really want to plug a new podcast that I’ve been listening to. It’s called the Code Newbie Podcast.
SARON:
Woohoo!
CHUCK:
And Saron does it. I just, I’ve listened to the first few episodes and it is a new favorite.
SARON:
Aww thanks. I did not pay him to say that, just for the record. [Chuckles]
CHUCK:
You didn’t pay me enough to say that. [Chuckles]
CHUCK:
But anyway, I really want to give a shout-out since she’s on the show. And I think it’s a terrific resource. So, even if you’re not a code newbie per se, we’re all newbies in some way. And I’ve learned a ton from her. So, that’s my plug. Yeah, let’s get going with the show. Pete, do you want to give us a brief introduction of who you are?
PETE:
My name is Pete Hodgson. And I’m a consultant at a software consulting company called ThoughtWorks, the one that Martin Fowler works at. And yeah, that’s me I guess. I’ve spent the last few years working in a bunch of different tech stacks. Quite a lot of Ruby, quite a lot of Rails, but also iPhone and JavaScript and Scala, and lots of different toys that I’ve been playing with in the last few years.
CHUCK:
Very cool. And Martin Fowler actually knows who he is because he recommended Pete to me for The iPhreaks Show. So, we talk every week.
PETE:
Right. Martin Fowler knows who he is. [Laughter]
CHUCK:
Now I’m confused.
PETE:
I’m confused.
CHUCK:
So, you don’t just work at ThoughtWorks. You were personally recommended for The iPhreaks Show.
PETE:
Yeah. Well, that’s nice.
CHUCK:
Smart person. You gave a talk at Rails Conf.
PETE:
That’s right, yeah. What was the title of my talk? I actually don’t remember. Rails as an SOA Client.
CHUCK:
Yeah. So, how does that work?
PETE:
So, I guess the talk was a little bit sneaky. It was a little bit about Rails as an SOA client. But it was also quite a lot about just working in a service-oriented environment in general and how to build systems that get along together partly by building teams that get along together. So, there’s a little bit of stuff around Conway’s Law and then quite a lot of stuff about the tech-y details of Rails and how it works as a client in the ecosystem.
So, maybe good to start with a definition of what I mean by Rails as an SOA client. Basically it’s this idea that rather than, historically we had these monolithic Rails. Initially when we, everyone built their first Rails application it was a Rails app that talked to a database and that was about it. And then maybe along the way we start integrating with third-party services, so Facebook or Twitter or something like that, some kind of external API. But then also, a lot of the times particularly nowadays, we’re integrating with internal systems like internal services within an organization. And we’re also starting to take our big monolithic Rails applications, our mono-Rails and break them up into small collaborating services.
So, what I’m interested in or what I was interested in this talk was talking about how you can build a Rails app that’s a frontend to these services. So, it’s a client in the client-server sense to backend services, which may or may not even be implemented in Rails or in Ruby for that matter.
SARON:
So, in the talk you mentioned Conway’s Law which says that how people work together affects system architecture and vice versa. How does that relate to SOA?
PETE:
So, that’s a good question. By the way, I always have a really hard time describing Conway’s Law. And I figured out the best way to describe it the other day. Software systems, oh what is it? Dogs look like their owners. [Laughter]
CHUCK:
I love it. [Laughs]
SARON:
That’s great.
AVDI:
That’s a great way of describing it.
PETE:
[Chuckles] Yeah. So, the way that it fits into SOA is, so this Conway’s Law thing is the shape of your teams inevitably influences the shape of your architecture. But it’s not, and it is the law in that it will happen. You don’t get to push against it and fix it. It’s like gravity. It’s going to happen to you. But you can choose whether to wield Conway’s Law to your advantage rather than yield to it and have it beat you up.
So, the reason that’s relevant for SOAs and service architectures is if you try and align the boundaries of your teams with the boundaries of your components, then you’re going to have a better time than if you try to have components that are shared by multiple teams, for example. And part of it is embracing the fact that your teams aren’t going to be as good at communicating across team boundaries as they are at communicating inside of the team and saying that’s okay. And not working the same way across teams as you would within teams, not just in the way the team members communicate but also in the way that you integrate services from different teams.
CHUCK:
Yeah, I think the way that I initially heard it described was that the structure of the application will mirror the communication between the teams.
PETE:
Right, right. And so, there’s this thing that I think Netflix originally popularized, this idea, and Amazon also. They structure their teams to mirror what they want their architecture to be to push the architecture in the right direction. So, Amazon for example has this idea of a two-pizza team where if their team’s a bit too big that they can’t be fed with two large pizzas, then they want to break that team apart. I’m pretty sure part of the reason why they do that is so that they can, because it forces them into an architectural pattern of small, decoupled services which can evolve independently. That’s a good thing from a technical point of view. So, they’re doing this interesting thing. And Netflix does the same thing of structuring their teams to let the architecture naturally evolve rather than fighting against the structure of the team.
CHUCK:
So, how do we structure out SOA so that we can take advantage of this kind of phenomenon?
PETE:
I’d put it the other way around and I’d say how do we set up our teams and how the communicate to embrace the nature of the architecture we want? So, one of the things that I talked about in this talk was talking about being able to work on your code in isolation. So, let’s imagine you’re writing a Rails app which I backed by a bunch of services. So for example, you’re building n ecommerce app and you’ve got the frontend is Rails but when it wants to list the deals of the day, it has to go into a deals of the day service. And when it wants to get the product images to put in that deals of the day section of the page, it has to go off to some catalogue service or something like that.
Now in a lot of cases, in a larger enterprise-y landscape those services are going to be managed by different teams. And what I’ve seen happen a lot in the past, particularly as people move from monoliths into these services, service-shaped worlds and particularly as teams start to, as organizations grow and they start to break up into multiple teams, at first you just want to stand up the whole stack and run the whole stack together, because it’s actually easier that way. A monolith is actually pretty easy to work with because you just pick it up and move it in one big chunk. And everyone has the same monolith and it’s quite easy to manage. But that doesn’t scale in terms of teams. It doesn’t scale technically as well. But it doesn’t scale in terms of teams so what you end up starting to do is break up into multiple teams, to their own multiple services.
But now if you have those services coupled together in that you can’t stand up the Rails app without those services being there, then now your teams are coupled together. So now, every time the green team introduces a bug, the red team gets really mad about it because now the red team who are looking after the Rails app can’t even launch their application because the deals service is down again. Oh, those guys don’t know what they’re doing.
So, I work quite a lot in larger organizations and that’s a very, very common phenomenon, is people beating up on other teams because their services are down. And oh, those guys are such a bunch of jokers there. Their thing is down twice a day, that kind of stuff. So, rather than fighting against that and saying, “We’ve got to make sure that everyone’s service is up all the time,” instead I think it’s useful to look at how to isolate yourselves in some aspects of your work so that you don’t rely on every one of your dependencies.
AVDI:
In your talk you describe this as the difference between codependence and independence.
PETE:
Yeah. Yeah, so codependence is like everyone has to be here for us to do anything kind of phenomenon. And it’s great when you can do it. Inside of a team, you’re codependent. So, inside of your team that’s building your software it totally makes sense for you to be codependent because you get a lot of benefits from that. You have a really high boundary of communication. When you’re breaking each other’s stuff, it’s actually quite good because it forces you to talk to each other.
The problem is if you stick your fingers in your ears and say, “Oh, this will work exactly the same,” even though the other team is on a different floor of the building, or is in a different continent maybe. So, in that case you want to be independent from those teams I would argue. It doesn’t mean that you can’t be friends. It doesn’t mean that you can’t collaborate together. But it means not kidding yourselves that you’re going to work exactly the same way with someone in another country as you would with someone who sits next to you and you have a standup with them every day.
AVDI:
Or even someone on a different release schedule, right?
PETE:
Yeah, exactly. Yeah, very good point. So, decoupling the teams means that you can decouple the services and vice versa. And that means that when you’re ready to roll out your software, you’re not held up because some other team slipped because they had some bugs they weren’t expecting or has a different set of priorities. That’s the other thing that you see with different teams, is they have different priorities which comes down to organizational management-y stuff. But still, it kicks in. If one of your dependencies can’t release something because they’ve had some red hot high priority issue come in from somewhere else in the organization, if that stops you from releasing then now you’re coupled to random parts of the organization, which [inaudible] you don’t want to be.
SARON:
So, what are some of the things that you can do to move towards codependence?
PETE:
Do you mean codependence or independence?
SARON:
Sorry, independence, yes.
PETE:
Yeah. So, it’s about decoupling. And that’s about looking at where you have those dependencies on a service being up for example, or on a service being at the same version as you and then using techniques to break that dependence.
So, one of the techniques that we use a lot around test automation is to create fake versions of our dependent services. So, in almost every project I’ve been on, we’ve done this at some point where if we require the deals of the day service to be up in order to launch the home page, at some point we build a fake deals of the day service that always returns some generic data.
And initially that might just be used for manual testing just so that you can stand up the Rails app on your laptop without having to stand up the entire enterprise infrastructure on your laptop. But quite quickly, what you can get to is starting to use those fake services for testing as well, because obviously you want to make sure that yes, you want to be independent from teams that aren’t necessarily sitting right next to you. But at the end of the day, you’re releasing a product that is the combination of all of these different services and all of these different teams. So, you do need to be able to verify that you can work together nicely. And so, faking out services is one way to do that.
So, you can simulate for example, let’s say you are getting ready for your winter holiday sale. And you know that during the holidays the deals of the day is going to have 20 items in it rather than 10 items. If you wanted to test that and you were only using the real deals of the day service, you’d have to figure out how to configure it and get it set up in some environment somewhere and test it. Alternatively, if you’re using fake versions of those services then you can just stand up this fake version and configure it to simulate the scenario that you want to configure. So, it’s actually really beneficial as well in terms of being able to test edge cases and scenarios that shouldn’t happen but eventually will happen.
SARON:
So, the idea of faking it makes a lot of sense to me. But at some point, you do have to test it against the actual service, right?
PETE:
Yeah.
SARON:
To make sure that it works the way you think it works. And I think that’s called contract tests. Can you talk a little bit about that?
PETE:
Yeah. So, contract test is this idea, the challenge as you’re saying where if you’re testing against a fake version of the services, you’re essentially testing against your understanding of how this other service works. So, because you’re not actually talking to the blue team’s deal service, if they change the way their deal service works or if you just misunderstand how it works in the first place and they start returning date times as seconds from the epoch rather than ISO 8601 or something like that, they change the format of their data structures or they add a field or they remove a field, you’re not going to know from your fake services because your fake services are fake. They’re not the real deal.
So, one of the antidotes to that is to write contract tests, and these are also sometimes described as consumer-driven contracts. And the idea there is the consumer of the service writes tests against that service that basically encapsulate what they expect that service to do. So, they’re like a contract between the two. They become a contract between the two teams essentially, where the consumer of the service gives these tests to the provider of the service and says, “If you can get all these tests to pass, then as far as I’m concerned you are doing everything I need from you as a service.”
So, we might write some tests that make sure that when we call the deals of the day it comes back with these values. Or if it’s a login service then we write some tests where we give it some good username and password and make sure it comes back with the expected response, and a bad username and password and make sure it comes back with the expected response. So, this is a way to encapsulate a communication mechanism between the two teams where you write the tests and give them to the team and then the team knows whether the tests are working or not.
AVDI:
My experience with building fakes like this has been mixed, because I have memories of spending a lot of time just maintaining the fakes.
PETE:
Yeah.
AVDI:
Keeping them synced up with their real counterparts.
PETE:
Yeah.
AVDI:
And just sinking a lot of time into that. Have you come up with any strategies for minimizing the time spent on that?
PETE:
I definitely have felt that pain as well. There’s a more sophisticated variant of the consumer contracts thing where essentially you insert a shim in between your service, or sorry, your code, let’s say if you’re a Rails app, you’re the client and the service, it’s like an HTTP proxy of some kind. And what that will do is it will record the requests coming out and be able to play them back at a later point. You can then use that same shim to verify your contract tests and use the output of those contract tests as the input for your fakes. So, this is definitely pretty high-grade sophistication.
I’ve actually never done this because it’s a lot of moving parts. But it’s become a bit simpler in the last couple of years. There were a couple of gems released by a couple of teams. So, there’s a gem called pact, P-A-C-T. And there’s another gem called pacto. And both of those are tools that you can use to do this kind of consumer contracts that also provide fakes. So, they’re two-faced if you will. As far as the consumer is concerned, they’re providing a fake service and then as far as the provider is concerned, they’re providing a set of contract tests against that provider.
I think that they’re used by fairly large organizations. So, pact is used by REA which is one of the biggest, it’s the real estate company in Australia as far as I understand. Maybe pact or maybe pacto, I get the two mixed up. And then the other one is used by Rackspace a lot to test their APIs for their OpenStack stuff, I believe.
AVDI:
So, effectively the fake is able to test its own assumptions about the real thing.
PETE:
Yeah, exactly. Exactly.
AVDI:
Interesting.
PETE:
Yeah. It’s a really cool idea. I haven’t used it myself in [inaudible] but I know that there are ThoughtWorks teams that have had a lot of success with it.
CHUCK:
Well, ThoughtWorks is listed as an author on pacto.
PETE:
Yeah.
CHUCK:
I’m curious. So, I’ve done this but I’ve also done, or at least built fakes like what Avdi was saying. I’ve built fakes and then had to maintain them. I’ve also just used something like vcr and fakeweb to basically record a response and then just play it back. The problem I’ve run into with that is that if the API changes then you have to re-record. And a lot of times, you have to wind up sending it a different set of data. And so, your assumption changing creates a whole lot of work and you have to maintain basically your recipe for getting a recorded response. I’m just curious. When would you use something like this with the fake service and when would you actually go ahead and use something like vcr where it’s just, “Hey, I think I know what the response is going to be?”
PETE:
Yeah. Fundamentally, they’re kind of the same idea. It’s just really, so the distinction I make which I’m not sure if it really makes that much difference, but there’s in-process versus out-of-process. So, things like vcr and webmock are running in the same process as your Ruby app. But you’re still doing the same thing as these out-of-process tools where you’re essentially just sticking something in between the client and the server and simulating, either recording and playing back or just simulating the responses.
I think in different technology stacks it’s quite nice to be able to share the same thing between technology stacks. So, for example if you’re building an iPhone app or an Android app or some of your consumers are Java and some of them are Erlang or whatever, then using an out-of-process tools means that you can share that tool across those different tech stacks, because those out-orprocess tools are just using HTTP. The flipside of them is that you have less control of them during tests because you can’t just reach directly into the thing that’s running the tool. So, it’s tradeoffs.
I end up preferring out-of-process ones just because they feel like they’re testing more of the system. But I think it really depends on your context. If you’re a Ruby shop and you’re just doing Ruby then using something in-process like vcr is actually, would work just fine as well.
SARON:
So, in the scenario that you created in your talk, each service is run by a different team, right? So, you had the products team running the products service, the deals team running the deals service. And then you’re in the middle switching between the two and you’re the Rails app. And a lot of the communication between you and the services is done via just code and test inspects and contract tests and such. When is that not enough? When if ever do you need to actually go to the other floor or across the building?
PETE:
[Chuckles]
SARON:
Like sit down and have a real conversation. When is that more useful?
PETE:
Always. Every single time. [Chuckles] That’s a great question. So, as software people we want to solve all of our problems with technology because we don’t want to have to interact with people, right?
SARON:
This is true.
PETE:
[Chuckles] So, this is something I spend a lot of my time doing, is telling people to get up and walk over there and talk to the person. [Chuckles] So, it’s always better to have a more higher bandwidth form of communication. And having a conversation with someone about this stuff is way more useful overall. I would always prefer that. But it’s not an and, or it’s an and. So, you can choose to do both.
The place where these tools are very helpful are instances where, I don’t know, if I’m taking off my diplomatic consulting hat for a second, instances where you have to hit the other team over the head with the truth and they don’t believe you. So, a lot of times, particularly there’s a team that you haven’t had the opportunity to build any kind of personal communication with, if you tell them, “Hey, every now and then your deals service is returning things with a missing field,” they’ll probably not believe you and they’re just say, “Oh, you’re probably calling us wrong.” That’s almost always the case. They’ll say, “Oh, well you’re probably just calling us with some invalid data.
CHUCK:
Works on my machine.
PETE:
Exactly, because that’s another part of being a software developer is we’re pretty convinced that we’re better than everyone else. Despite Impostor Syndrome, I think there’s always an assumption that we understand things. And so, if someone else thinks that something’s broken, it’s probably because they don’t understand things as well as I do.
So, one of the really nice things about these contract tests is they help to solve this game of who’s bug is it anyway where everyone insists that their code is doing the right thing and it must be someone else’s problem. And there’s a lot of finger pointing, not necessarily in a toxic, aggressive way, just in a natural assumption way like, “I’m busy. I’m not sure whose problem it is. I’m pretty sure my stuff’s good, so I’m just going to assume it’s someone else’s problem.” And you get this tragedy of the commons where everyone thinks it’s someone else’s fault and no one fixes the problem. Contract tests are really good because they very reliably test the same thing over and over again. And they produce a lot of documentation about what was sent to the service and what its response was.
So, I’ve had real life examples in a project where we had a service that was consistently challenged. We got to the point where the CI system would run these tests on a regular basis, like maybe every hour. And when they broke, we’d notice that the builds had turned red, we’d go to the CI thing. We’d be like, “Oh, there it is. Deals service again,” copy paste the output from CI into an email and send a nice email to the team saying, “We’re pretty sure that we’re using your service wrong. It must be our fault. But when we ask you for the deals of the day, you’re returning a 500 error.” So, that is actually really helpful because it helps that team debug the issue. They’ve got a really solid reproduction case rather than us just saying, “Sometimes your service doesn’t work properly and we’re not sure why.”
AVDI:
I love the way you phrased that.
PETE:
Yeah. [Chuckles]
PETE:
Yeah, that’s me putting my consulting hat back on again. [Chuckles]
CHUCK:
Well, and you framed the conversation around this a little bit by bringing up Conway’s Law, but at the same time it’s funny how we talk about these technical issues around consuming services and building services and what we’re talking about is how to talk between the teams, how to facilitate the communication.
PETE:
Yeah.
CHUCK:
And how facilitating that communication is what makes the technical issues work themselves out.
PETE:
Yeah. Yeah, so this is a really, this is a total sidebar, but this highlights why things like improving the diversity of our industry is super, super valuable, because diverse people have different ways of talking to each other and they can actually communicate with each other better. Having five different people that have five different backgrounds that have five different communication styles, one of them will be able to relate to the other person on the other team and have a conversation. And building software is a team sport. Maybe it didn’t use to be, but it’s absolutely a team sport and it comes down to people all the time. So, if you can have a good team that can communicate with each other, then that trumps algorithmic efficiency every day of the week, in my opinion.
CHUCK:
The thing is, is if you, algorithmic efficiency, you’ll save money at scale. However big the system is, it’s going to save you that much money. But in my opinion, most systems, some call the same call and so, you’ll save thousands and thousands of dollars by making that change. But that’s at scale. On most systems that I’ve worked on, they’re not at that scale. So, the big expense isn’t the infrastructure, it’s the people.
PETE:
Right.
CHUCK:
And so, if you can get them to communicate so they’re not spending as much time banging their heads against the wall, that’s where you’re going to save money, or that’s where you’re going to get more done. You’re going to get further ahead of your competitors and be more competitive and things like that. And so, ultimately what we’re talking about here really does affect the bottom line of the companies you’re working for as well.
PETE:
That’s the fundamental argument of Ruby, right, is developer productivity trumps CPU efficiency. I’d rather have an effective team than an effective program. If you’re able to in general produce software faster, that gives you way more time to do the profiling to find the one part of your codebase that needs to be optimized and then spend the time optimizing it. So, you actually end up with a more effective codebase anyway, if you’re doing it right.
CHUCK:
Yeah, totally agree. Is there any other aspect of the social or team dynamic people problem, things that we should talk about before we get into the technical details of how this all sits and hangs together?
PETE:
The only other thing I’d highlight is that it’s important to understand, once you get to this level of having different kinds of tests, you’ve got your unit tests and then you’ve got some isolated test that you use in these fake services. And then you’ve got your contract tests, et cetera, et cetera, it’s important to start looking at this as a, start introducing some of the concepts of continuous delivery and look at this as a pipeline that your software is going through. And as you check in code, you start off with just the unit tests. And then the analogy that Jez Humble, the guy that wrote the CD book uses, is it’s like you’re putting your code through like an assault course. And the obstacles are getting higher and higher as it goes.
So, you start it off by just seeing if it can pass its unit tests. And then you say, “Okay, great. Well, you can pass a unit test. How about your isolated functional tests? Okay, good. Now are you able to communicate with this other system?” And setting up as a series of more complex tests and tests that are more integrated as you go means that you get fast feedback early on if it’s your bug, but you’ll get feedback on the integrated system quickly as well.
So, just using these tools and then running them ad hoc is better than nothing. But you really get the most bang for your buck out of it if you’re able to run them on a very consistent basis and run them when your code changes and run them when the other person’s code changes so that you can see the delta and get faster feedback.
CHUCK:
I also want to point out that during your talk you kept picking on team D and I kept thinking to myself, “Yeah, they’re definitely not the A team. They’re the D team.”
PETE:
[Laughs]
SARON:
[Chuckles]
PETE:
Yeah. Actually, I exaggerate for effect with this stuff. But I’ve very rarely worked with teams that don’t want to do a good job. And it’s very rarely that the team isn’t capable or isn’t smart. It’s normally that they’ve got other stuff going on, like the reason their stuff is breaking is because they’re under a huge crunch in some other part of the code they maintain. And they’re just not paying attention to this stuff because it’s not on their radar right now. So, it’s generally not like team D are the dummies. But it’s fun to turn it into a joke, especially when it’s an anonymized team like team D. No one really cares about team D.
CHUCK:
Yeah. Well, the other thing is that you’re not going to get anywhere even if they are the guys that are a little bit slow. If you come in and you’re like, “Okay, you idiots. Let’s get this working.” You know.
PETE:
Yeah.
CHUCK:
And we’ve discussed that already. But yeah, I think we all have our egos. And as you said, we all kind of think we’re right. And so, it’s really easy to go in and just assume that they did something dumb. And sometimes it is some dumb little syntax error or something. But if you haven’t ever done that, come fine me because I want to hire you, okay?
PETE:
[Chuckles] Yeah, exactly.
CHUCK:
So, let’s talk about the technical end of this. You recommended that people use Faraday. Do you want to explain just a little bit about what Faraday is and how people use it?
PETE:
Yeah. So, Faraday is like Rack but upside down, is how I describe it. So, Rack is this system that underpins your Rails apps. It underpins almost every HTTP app that you would do in Ruby. And it’s this abstraction over the concept of HTTP. So, requests come in and responses come out. And you can have those, you assemble this kind of stack of middlewares. And they each, as a request comes in, it passes through each layer of that stack. And that stack is able to modify that request in some way or to take some action based on that request. Eventually that request gets to your Rails app which in fact your Rails app consists of a ton of different Rack middelwares. That’s actually internally how it’s structured these days.
So eventually, this request comes through the stack of middlewares, gets processed by your business logic, and then heads out back down the stack the same way it went in. And on the way out, all those pieces of middleware are also able to modify the response in some way. So, this is the way that you do logging, and maybe enforce security. You put some authentication thing in there and add extra headers and compress your assets. And all that kind of stuff can be done by modifying your request as it comes in and modifying your response as it comes out. So, that’s Rack.
Faraday is the exact same concept but for the client side of things rather than the server side of things. So, it’s this same idea of this stack of middlewares that instead of it being on a server it’s on the client. So, when I make a request as a client, when I make a request to some remote server, my request won’t go on the wire straight away. It will first travel through this stack of middelwares, which are again able to modify that request on the way out. That request thing goes to that external service. The external service does whatever it’s going to do. It sends a response back.
And then as the response comes back in, again my stack of middlewares, my Faraday middleware, is able to modify that response as it comes back in. It’s very, very similar. It’s a really, really elegant way of splitting your application into the boring tech-y network stuff versus the interesting business domain-y stuff. And Rails uses this to great effect with Rack on the server side of things. Faraday lets you use the same techniques on the client side of things to keep your business logic focused on the business and keep your boring network-y stuff like logging, requests, and compressing things, and parsing, and all that kind of stuff isolated from the business logic.
CHUCK:
Yeah, I tend to explain middleware as lenses or filters. And so, some things are going to filter different colors or different shapes or different things like that, so different parts of the request going out or coming in, or response going out or coming in. And so, in a lot of cases it’s just going to leave it alone. And then in some cases, it’s actually going to handle change or otherwise manage the information that is going past it. And so, it goes all the way to the bottom and then climbs all the way back out.
PETE:
Yeah, exactly. And Faraday works in that exact same way of, it’s a classic pipes and filters Unix type deal. And people who’ve had the curse of working in Java, it’s like servlets. It’s a very common pattern in a bunch of different technology stacks actually.
CHUCK:
Yeah, and with Rack it’s requests coming in and responses going out. And with Faraday, it’s requests going out and then responses coming back.
PETE:
Yeah, and it’s a lot easier if you look at a picture. [Chuckles]
CHUCK:
Yes.
AVDI:
So, how does this fit into your SOA systems?
PETE:
This is coming a lot from a specific project where I used Faraday and was really, really happy with it. So, we wanted in this project to stick with this idea of hexagonal architectures. This is the idea of basically keeping your core business domain, the reason your app is actually doing something, separate from all the boring technical goop. Your goal is to push all of the tech-y stuff like hitting the database or rendering HTML or making network calls out to the boundaries of the system and then establish a really nice, defined boundary I guess in between the tech-y stuff, the network calls, the HTTP, the database, et cetera, and the business-y stuff.
And the way that we did that was building these things called service gateways which are equivalent to a repository if you’re talking to a database or maybe like an Active Record object, but for service calls. So, we built these service gateways, one for each external service we were using.
And the way that those internally were built was using Faraday as the client.
CHUCK:
So, one thing that I’ve done with this kind of thing is actually build an internal gem that codifies how to talk to the external service and then test that gem against the testing system and stuff. And so, I’d have a gem that basically wraps around Faraday and defines all of the middleware that goes in there so that it does the right thing when it’s making a request and then coming back as far as logging in everything else, because it can vary from service to service. Is that an approach that you’ve used? Or do you just use Faraday and set things up on a per-request basis?
PETE:
I’ve not gone to the extent of actually using the gem mechanism to package it as a separate module. We definitely would treat it as an independent library that we want to be able to exist in isolation. The implementation of this thing shouldn’t be coupled to any other part of the application. So, you should be able to test it in isolation and we did do that. We actually, often we would use the service gateways as the start of our contract tests. So, that was a nice way for us to test our service gateways, at the same time as testing our external services.
We essentially considered the service gateway to be part of that integration with the external service. And maybe if it was a larger system or if it was something that was more complex architecturally, then we would have pulled out those service gateways into independent gems. For our use case, it was enough just to have them as just plain old Ruby classes that we were able to use in both our tests and also in our production code, obviously.
CHUCK:
Yeah, and the case that I’m thinking of basically, it was just a convenient way to share code. We had several client services, so to speak, that would all speak to the same backend service.
PETE:
Yeah. So, there’s one, that actually touches on a really interesting point that takes us back to Conway’s Law. There’s always a strong temptation to have the team that maintains the service build these gateways. So, if I’m the deals of the day service, I build the deals of the day service gateway and package it up as a gem and then I just dump that gem. I export that gem into my, or consumers of my service can just pull that gem. And that feels like the right thing to do. It’s actually going to cause you, I think most of the time more pain than benefit.
And again, it goes back to Conway’s Law. If you think about where the team boundaries are, thus is where the code boundaries are, you’ve not got some other team inserting, tuttlling themselves directly into one of the really important parts of your codebase. And so now, every time you want to change, every time that team wants to change how they’re doing things, they need to change your code. And that can really lead to teams that are very tightly coupled together. And if they’re not able to communicate effectively, then it will cause more pain than good, in my opinion. But it’s very counter-intuitive because it feels like a much more efficient way of doing things.
AVDI:
Right, but the team that’s implementing that service, they don’t necessarily understand how you want to use the service.
PETE:
Right. And if there are different teams using the service in different ways, then by having one team define the way of talking to the service, now that team is responsible for the union of all possible use cases of the service. And that can put a lot of…
AVDI:
Right.
PETE:
Burden on the other team.
CHUCK:
That’s a really interesting point. Thankfully, in that case we were all the same team working on all the different services. So, it was less of an issue there.
PETE:
Yeah, yeah.
CHUCK:
I could go, I could walk around the pod of desks and, “Hey, you broke it.”
PETE:
Yeah. And in that case, it absolutely makes sense, because if you’re not pushing against the grain in terms of the team structure and the code structure, then go for it. But it’s when you notice a distance between the way the teams work and the way the code works, that’s when alarm bells should be ringing.
CHUCK:
Yeah. So, you’re using Faraday. You have these services set up. We talked a little bit about testing it before, but how do you verify that the whole system is playing nicely together? Do you recommend that people set up a staging setup and test it that way? Or is there a different approach that you recommend there?
PETE:
It’s tricky. At some point, it gets back to that continuous delivery idea. To start with, maybe you want to test these things against fake services just to make sure that they’re fundamentally working. The next thing you probably want to do is stand up, if you can, my preference is to stand up a disposable environment essentially of all of the services, the immediate services that you depend upon, and test those integrations and then just throw that environment away when you’re done. And if you’ve got things like Vagrant and Docker there, and Chef and Puppet, then this makes that kind of practice a little bit easier.
Realistically for most larger service architectures, what you end up doing pretty quickly is integrating by putting everything into a shared integration environment or staging environment and then running a lighter set of tests against that staging environment. But what you really don’t want to do is use that staging environment to test the functionality of your application. You should have already verified the functionality of your code using unit tests and low-level tests. You should only really be using that staging environment to test that the integrations that you’ve built work in the way that you expect them to work.
SARON:
So, does it make sense to have a shared dev environment and a shared staging environment?
PETE:
So, a shared dev environment I think is sustainable for a period of time. But at some point, if you have enough teams sharing that environment, something is always broken. If you’re doing a good job as a software engineer, you’re breaking stuff at some point. If nothing’s ever broken, then you’re probably not working hard enough, in my opinion. So, the challenge of a shared environment is eventually it gets to the point that so many teams are committing code to that shared environment so fast that it’s often broken. And once you get to that point, then I’ve seen a lot of teams move towards standing up their own versions of their own kind of environments that have copies of their dependent services.
So, if it’s the team that’s building the ecommerce app, they might have a shared frontend set of services, but they’re all talking to the same SAP installation or something like that, because it doesn’t make sense to have and SAP installation per developer. But it also probably doesn’t make sense to have an SAP installation that’s shared across every developer in a large organization, because at some point two developers are going to want a different version of something to be there. So, you start having to have a series of shared environments.
CHUCK:
It also sounds thought that you’re almost getting to where, I don’t know, you have to do these big planned releases then, instead of just deploying one at a time because you do have that interdependence then, instead of independence.
PETE:
Right. Yeah, that’s a really, really good point. So, that gets to something which I actually didn’t talk about in this talk because I didn’t have time: the idea of feature flags and being able to release latent code. So, code that is there and ready to go but hasn’t been turned on yet. And that’s the best way I’ve seen to decouple releases from each other. So, I think when you guys had the episode with Badri and Mo talking about extreme deployments, I’m doing air quotes, how it works.
Was it extreme deployment?
CHUCK:
Yeah.
PETE:
That was what you guys called it, right?
CHUCK:
Yeah.
PETE:
I think there was a, they touched briefly on this idea of feature flags or feature bits or feature toggles where you have code that’s… so, let’s say you’re integrating with a new, so the deals of the day team have been hard at work. And they’re getting ready to release deals of the day version 2. It’s a greenfield reimplementation of deals of the day in Rust. And you want to use this new service. And they have guaranteed that it’s going to be delivered in next month’s release. So, you build code that’s coupled to that service being there. If that service isn’t there, then you can’t release your code. So, that’s the thing that you don’t want to happen, is you’re coupled to this release. Because if their deadline slips or if they have some other priority they need to do, and their new service doesn’t get out or their new version of the service doesn’t get out, then now you can’t g et out either.
The way to get around that and the general approach to solve this is to use a feature flag and be able to turn it off and on. So, your code ships with the latent ability to use the new deals of the day service. But it still has the ability to use the old deals of the day service. And that means that if everything goes according to plan, you ship with that feature bit turned on. And you can talk to this new Rust-powered deals of the day service. But if things go south, then you just ship the same, you release the exact same day just as you are planning. You just turn the feature bit off. And then two weeks later, blue team or whatever the team is, they’ve pulled their all-nighters and they’ve finally got their Rust service out into production, you just flip your feature bit on and start using the new service. And then a couple of weeks later, you deprecate the code that was using the old service. And then you delete it from you codebase a couple of weeks after that.
So, that’s the way that you decouple the release trains of these different teams. And I used an extreme example of a brand-new service. But you can do the exact same thing with an API slightly changing. So, it used to be that the first name and last name were two separate fields and now they’re one field joined together. You can use feature flags to control how you consume that service’s API so that if their release doesn’t go out, then you’re not going to break.
CHUCK:
Nice. I like it. So, have you built any apps that rely solely on services? In other words, there’s no database? The database is that other service?
PETE:
Yeah, so that was actually the case with the app that was the inspiration for a lot of this, the app where we used a lot of Faraday. That was the first app I’ve worked on, I think, well first Rails app I’ve worked on where there was literally no database at all. It was all backend services. And it was an ecommerce app. It was for an online book retailer. And yeah, they had a bunch of existing services in Java and .NET and they wanted to build a nice API, or a nice UI to release to a new geography. And so, we built this Rails app that was, we literally deleted Active Record, the Active Record gem from the gemfile, which was very satisfying.
CHUCK:
[Laughs]
PETE:
[Chuckles]
CHUCK:
You know there’s a flag for that, right?
PETE:
Yeah. I was, I don’t know, I got some catharsis from deleting Active Record.
CHUCK:
Yeah.
PETE:
And it was really interesting, because you get all of these weird, there’s a lot of stuff that you have to look at in terms of making a Rails app performant in that context. So, caching for example was a really, really big deal for us because every page we rendered involved multiple service calls to services where we had no control over their response times in some cases. And some of the service calls were quite expensive. Looking up a product price is surprisingly expensive. So, we put quite a lot of work into figuring out how to get these service gateways, these stacks of Faraday components, to add performance things like caching without us having to think about it inside of the business code, again going back to that hexagonal architectures thing.
CHUCK:
So, that leads me to another question and that is, is there something that you can build in to Faraday to handle unreliable or unresponsive services? Since you don’t have control of the service.
PETE:
Yeah. You essentially can make Faraday work like your browser works. So, as web developers if you’re building a Rails app you understand quite well, hopefully you understand quite well how caching works. And you put caching headers, make sure that there’s caching headers on your images and figure out how to set your ETags correctly so that you can send back 304s rather than re-rendering things, all that kind of stuff. So, we do that a lot as HTTP on the server side of things. We do that because the browser is optimized, quite heavily, very heavily to do caching.
So, a browser will try really hard to not make a network request. And if it is going to make a network request, it will try very hard to use what it’s got in its cache rather than actually pulling all of the data down over the wire. So, we configured Faraday to do the same thing. We essentially set up Faraday to be a little mini-web browser where each gateway had an internal cache. And it would try really hard to respect the caching headers that it was getting back from the services that we were using.
So for example, product prices are very, very dynamic. They’ll change multiple times a day in some cases, so they’re not very cacheable. Product information, the title of a book, an ISBN, is obviously very, very static. It very rarely changes. So, our services would send back caching headers that encapsulated that. So, our services would, when you made a service call to get product details, it would have quite a long cache time because it doesn’t change that often. Conversely the pricing service would have cache headers that basically said, “Don’t cache me. You need to call me every time. Sorry, but prices change a lot.” And we were able to set up a Faraday stack that would use those caching headers to cache information.
And what was really, really nice about this is it put control of the cacheability of data with the team that owned that data. Again, it goes back to Conway’s Law. As a consumer of the service, I know less about its cacheability than the provider. The pricing service, they know how often their prices change. So, they should be the guys that say how cacheable it is. Likewise, the product team, they know how to build an ETag that represents that resource. So, they should be the ones building it. And we should just be following their lead as a team. So, setting up the architecture that way again lined up the team boundaries with the technical boundaries.
CHUCK:
And then do you just split out? So, when I request a book, it didn’t come with the price included so I’d have to go to the pricing endpoint and ask for that just because it had a different life cycle than the rest of the book information?
PETE:
Yeah. That’s actually a fairly common pattern with more sophisticated web applications. So, it’s called segmentation by freshness. So, if you don’t do that, then everything has to be, you get this cascading effect where the entire set of data has to have the cache time of the most time-sensitive thing. So, imagine your Twitter feed for example. When you load the Twitter homepage, the whole homepage can only be cached as long as there might not be a tweet. But really, the only thing that changes there is the bit in the middle with the tweets. All the rest of it is actually separate.
AVDI:
So, I have some questions about managing this caching. Was this all in memory, in your server processes? Or did you save off the caches somewhere?
PETE:
So, the really weird part about Faraday is it’s so similar to Rack that you can actually put this adaptor into a Rack middleware and turn it into a Faraday middleware. We were actually using the Rack caching middleware adapted to sit inside of a Faraday stack. And that Rack caching middleware has a lot of different options for storing it. So, you can do in-memory. You can do ondisk. You can do memcached. You can do, I think Redis. There’s a bunch of different options. In our case, we used the file system because it was easy to set up and just seemed like the simplest way to do it to start with. But we had the option of changing where that caching was stored very, very simply. It’s literally just a one-line configuration change inside of the middleware to say rather than writing to this directory on disk, write to this memcached location.
AVDI:
And did you ever have trouble with cache-busting? Like, values that just were stubbornly the cached version when you really wanted the fresh version?
PETE:
I don’t think so. We did have issues where we had to talk through with the other teams how to set the headers correctly. We didn’t ever have a situation where something was stuck in the cache. In general, we had the other problem where there weren’t the caching [inaudible] that we wanted. So, we weren’t using the cache at all. That happened quite a lot and that was a thing where we had to go to the different teams and say, “Hey, we’re respecting caching headers. You should probably use some of those, please.” But I’m not aware of any issue where stuff got stuck in the cache necessarily.
AVDI:
Okay.
PETE:
In reality, most of the time we wouldn’t need to go onto the network. There were a few things like the list of states that you support. Stuff like that you can cache that for quite a while. You could probably cache that for a day and it’s not going to be the end of the world. So, there are a few referent services that were cached enough that we literally didn’t go on the wire if we’d recently seen a new version of that resource. But most of the services were not, we would still have to go to the service and ask it if things had changed. So, a lot of the time…
AVDI:
So, you’re basically doing head requests?
PETE:
Yes, exactly, yeah. So, go to the service and ask. Well, you don’t even need to do a head request. You can make a regular GET…
AVDI:
Oh, I see, right. [Inaudible]
PETE:
Yeah. It just comes back with a 304, yeah.
AVDI:
Yeah.
PETE:
And again, exactly the same techniques that the browser uses very effectively today.
CHUCK:
Now, is there a lot of middleware written for Faraday or did you wind up having to write or adapt your own?
PETE:
There’s a fair amount out there. I’m trying to remember. There were a few little pieces that we crafted for ourselves around instrumentation I think, so tracking how long the requests were taking. And I think we had something that bridged between the Faraday stack and the thing that’s built into Active Support that does instrumentation, Active Notifications I think it’s called, something like that. So, we had something that we used so that we could centralize all of our instrumentation of how long both our requests and responses were taking and our client’s. And that was helpful for correlating what was making our webpage load slow.
So, there are a few little things we had to do like that. In general, the stuff that comes out of the box with Faraday, there’s some stuff that comes with Faraday by default. And then there’s a set, there’s a gem that has a set of extensions and useful bits and bobs for Faraday, the name of which I can’t remember. But generally, we just used the standard middleware components in most cases.
CHUCK:
Alright. Well, if people want to get a hold of you or ask you questions about this Pete, what’s the best way to do that?
PETE:
I am on the Twitters as @ph1 and I’m on email as phodgson, P-H-O-D-G-S-O-N at ThoughtWorks dot com. And yeah, I love, love, love talking about this stuff. And if anyone’s interested in debating it or talking about it more, I’d love to talk more about it. It’s something I’m super passionate about.
CHUCK:
Yeah. And if you want to hear Pete every week talk about iOS stuff, you can also go to iPhreaksShow.com.
PETE:
[Chuckles] That’s right.
CHUCK:
Alright, well let’s go ahead and do some picks. Saron, do you want to start us off with the picks?
SARON:
Sure. I have a lot of picks today actually. So, the first pick is Pete’s talk, Rails as an SOA Client. That was the one talk at Rails Conf that I was very, very upset with myself that I missed because it was really good. And I got a chance to watch it and prepare for the show. And I thought the way you explained things was just really beautiful and the way you explained hexagonal architecture with the picture and you led up to that, I thought honestly it was beautiful storytelling. So, I want to [inaudible].
PETE:
Thank you.
SARON:
You’re very welcome.
The second, you mentioned diversity and how important it is in teams. And one of my picks is actually a blog post called ‘Diversity Is A Superpower’. And I feel like a lot of times when I read blog posts on diversity, it’s usually an anecdotal story or just a personal experience thing. And this one was actually very, very fact and research based, which I really, really liked. And it talks about a lot of concrete, tangible benefits of diversity. And it cites different research papers on what you should know about it and how it impacts your work. So, I really like the different angle and perspective on talking about diversity. And I think you will too.
The third is a study group called RubyNewbies and it’s started by Brian Douglas who I actually had on the Code Newbie podcast. He’s a Rails developer and they are a group that does different parts of Newbie. And if you’re a little bit new, I think you’ll appreciate it. They’re going to be reading the POODR book starting October 7. And they meet twice a month. And I think that’ll be a great place for you to start if you haven’t read POODR yet.
My fourth pick is about cartooning. So, if you’ve seen any of my talks and you’ve seen that I love to put comics and cartoons in my slides and people often ask me how to draw and how they can do that. And actually, Chuck asked me this a couple of weeks ago. And so, there’s this course that Rachel Nabors who’s a cartoonist and interaction developer is putting on called ‘Cartooning For Tech Folk’. And I thought you’d be interested in that.
And the final pick that I have is called Octobuild and it’s by developer Richard Littauer. And the idea is, it’s like NaNoWriMo, if you’ve heard of that before, which is the challenge to write a novel in the month of November. And this is the challenge to start and hopefully finish some kind of a programming project in the month of October. And it’s a board. You post up the project. You can ask for help. It’s a great place to ask for support and collaboration. And so, if there’s an idea or a side project you’ve been thinking about and need a reason to get started, here’s your reason. And I’m going to join. And I’m excited to see everyone’s projects. That’s all I got.
CHUCK:
Awesome. Avdi, what are your picks?
AVDI:
You know, I got nothing this time. Sorry.
CHUCK:
Slacker.
AVDI:
Yeah.
SARON:
Did I take all of your picks, Avdi?
AVDI:
[Chuckles] Yeah, I seed my picks.
CHUCK:
You took all of his picks. He was totally going to pick the October developer thing.
SARON:
I knew it. Sorry, Avdi. Next week.
AVDI:
No, I wasn’t. [Laughter]
CHUCK:
Alright. I’ve got a couple of picks. They’re both books. One of them is called ‘Finding Ultra’. I might have picked it on the show before, but I don’t think I did. So, I’m going to pick it again. And basically, it’s this guy. He’s 40-something. He has trouble walking up the stairs, has shortness of breath, and this moment of, “Oh my gosh. I’m going to die,” and then realizes that, “I really don’t want to die.” And so, he goes through and starts training for an Ultra Ironman. And then it talks about the process that he goes through, basically changing his life. And so, there’s a lot in there about veganism and stuff that I just thought, “Okay, that’s interesting,” and got some ideas from it. But I’m not going vegan. However, there was also just a lot of terrific, “Go out and empower yourself and change your life,” in it. And so, I really liked it.
The other book I’m going to pick is there’s a new book out in the Michael Vey series which I have picked on the show before. Michael Vey and ‘Hunt for Jade Dragon’. If you want a, “I’m not really going to think about this,” story, it’s young adult fiction. So, not a tremendously wonderful book but I really did enjoy it. And I think it’s the best one in the series so far. And so yeah, I’m liking that.
And then my third book pick is ‘The Maze Runner’. They’re turning it into a movie. And again, I like it about the same as I like Michael Vey, so it’s not my favorite book. But I am enjoying it. So anyway, those are my picks. Pete, what are your picks?
PETE:
My first pick is going to be shameless self-promotion. We talked a little bit about this idea of feature flags and being able to ship code that’s on or off depending on a toggle. Me and a coworker made a gem probably a couple of years ago now called rack-flags which lets you do feature flagging in a very lightweight way. You don’t need a database. You don’t need anything else. You just need to stick this thing into your Rack stack and it lets you do really basic lightweight feature flagging. So, it’s a good way to get started looking at that technique. So, rack-flags is my first pick.
My second pick is the GoGaRuCo conference that just wrapped up last week I think in San Francisco. And I didn’t go this year and I’m super sad I didn’t because they announced that it was the last year they’re going to do it. It’s been one of my favorite tech conferences. I’ve been a few times and it’s just a really, really great conference. And they did a really, really great job with that conference. So, bittersweet that they’re wrapping it up, but just wanted to give them some love because they did a lot of hard work. And I know that running a conference is not an easy or necessarily a hugely rewarding in terms of money activity. So, lots of love to them.
And continuing on the loving theme, I’m going to pick Ruby Rogues. I’ve been listening to this show since episode one I think. I haven’t listened to every episode, but it’s just been one of my favorite podcasts. And you guys always have really interesting guests and very, very smart panelists. So, thank you for doing what you do for 176 episodes.
CHUCK:
Well, thanks.
PETE:
Yeah. My last pick is a beer because I like to pick beers. I’m going to pick Upright Four, which is a Saison wheat beer from Upright Brewing who are based in Portland, Oregon. It’s a really nice, light, very refreshing low alcohol but very full of interesting flavors beer. I highly recommend it if you can get a hold of it. Upright Four.
AVDI:
Hey, I realized I had a pick after all. All your book picks Chuck made me realize I have a book pick. One of my favorite book series is the Laundry Series by Charles Stross. And it’s a little hard to describe. It’s basically if you take H.P. Lovecraft and cross it with XKCD and Dilbert, you get the Laundry Series.
The basic premise is that these cosmological horrors hinted at in H.P. Lovecraft are totally real and totally interested in munching on everybody on earth. And magic is basically computational advanced computation. And so, computer programmers tend to be the ones that get sucked into fighting these beasties. The novels are written from the perspective of somebody who was a programmer and got sucked into the agency that’s responsible for keeping earth safe from these critters. But rather than being like an exciting ‘Men In Black’ big shiny guns kind of agency, it turns out that this agency is exactly like every other government agency.
[Laughter]
So, it’s mired in bureaucracy, and it’s full of cubicles. And when he’s not fighting tentacled horrors, he’s having to install new cabling because he also doubles as IT. And it’s written by somebody who is, I guess one of us would be the right way to put it. So, it is just riddled with references that you will get if you are a geek and a programmer. It’s a lot of fun.
PETE:
That sounds awesome.
CHUCK:
It really does. I also forgot to mention, if you are thinking about going freelancing, going freelance, The Freelancers’ Show panelists are doing a Q & A on freelancing. And you can go sign up for that at FreelancersAnswers.com. And it’s going to be live. It’ll be on October 7th 10 am Mountain Time. We’ll basically take any questions that people have about marketing, lifestyle, freelancing, all that stuff. So, if you’re interested then go pick that up.
The other thing that I keep getting asked about is podcasting. It seems like I’ve coached about four people in the last week, present company included. And I love doing it. I think I might be able to help more people if I do the same kind of thing. And so, I’m going to give an introduction and then answer whatever questions people have. And I’m not sure when I’m going to do that. But you can go sign up for that at PickUpPodcasting.com. So anyway, some self-promotion, but hopefully I can help some folks out. They’re going to be free. So, I don’t feel too bad about promoting it. But there you go.
AVDI:
Can I self-promote too?
CHUCK:
Yes.
AVDI:
Noel Rappin pinged me on Twitter and said, “Hey, by my calculation today is the two-year anniversary of the first episode of RubyTapas.” And I was like, “Holy crap, it is.” So yeah, I’m just going to say I’ve been doing it for two years and I’m excited about that. And it’s still going strong. And if you’ve been waiting all this time to see if I would keep at it to check it out, well I kept at it. So, go check it out. [Chuckles] RubyTapas.com.
CHUCK:
We’ve been doing this show for three and a half years, so I’m still waiting to see if you’ll keep at it. [Laughter]
AVDI:
Yeah, that’s a good point.
CHUCK:
I’m just kidding.
AVDI:
[Laughs]
CHUCK:
I love RubyTapas. It’s awesome. So yeah, definitely don’t miss out. Alright. Well, I guess that’s a wrap. Thank you all for listening and we’ll catch you all next week.
[A special thanks to Honeybadger.io for sponsoring Ruby Rogues. They do exception monitoring, uptime, and performance metrics and are an active part of the Ruby community.]
[Working and learning from designers at Amazon and Quora, developers at SoundCloud and Heroku, and entrepreneurs like Patrick Ambron from BrandYourself, you can level up your design, dev, and promotion skills at Level Up Con taking place October 8th and 9th in downtown Saratoga Springs, New York. Only two hours by train from New York City, this is the perfect place to enjoy early fall and Oktoberfest while you mingle with industry pioneers in a resort town in upstate New York. Get your ticket today at LevelUpCon.com. Space is extremely limited for this premium conference experience. Don’t delay. Check out LevelUpCon.com now.]
[This episode is sponsored by MadGlory. You’ve been building software for a long time and sometimes it’s get a little overwhelming. Work piles up, hiring sucks, and it’s hard to get projects out the door. Check out MadGlory. They’re a small shop with experience shipping big products. They’re smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter at MadGlory.]
[Hosting and bandwidth provided by the Blue Box Group. Check them out at Blubox.net.]
[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]
[Would you like to join a conversation with the Rogues and their guests? Want to support the show? We have a
forum that allows you to join the conversation and support the show at the same time. You can sign up at RubyRogues.com/Parley.]