I really don't want to handle the side effects of dubbing videos in my web app. That kind of stuff belongs in a dedicated service anyhow - big monoliths are really the killer of maintainability.
Just because it's popular to farm that out to another service (and another operations bill) in Ruby because, lets face it, there's not much alternative, doesn't mean it's the best solution. It's just the practical one given the constraints. Lift the constraints, expand your options and there you go.
Some of my others might seem silly to you. Fair enough. There's just at the top of my head.
Dubbing is an IO problem mostly, and pretty cheap. Unless you're doing a lot of it, adding complexity and (really large) performance hits by having to integrate with external services is not a "better" or "easier" solution if you can just say:
val dubbedVideo = Dub(inputVideo, newAudioSource)
Same for simple image resizing. You have to be pushing a lot of resize operations to make that something you'd want to farm out as opposed to just tossing 'em over to an actor system. And then you should probably be trying to bypass your application server entirely so you don't trade a CPU spike for a lot of IO. Again, more complex.I've worked in a number of very large Ruby apps. Did a lot of dumb things. Maintainability issues though? That hasn't come from ImageMagick, FFMpeg, Redis, etc. Those things are (mostly) just big up-front expenses. Would Zencoder have made any of our apps more maintainable? No. Absolutely, Definitely, Unequivocally not easier to maintain than the already simple internal API calls that haven't been touched much in years. Zencoder's API has changed more than our own I'm sure.
I would use Zencoder today as opposed to doing the same again. The up-front cost just can't be justified. But even so, maintainability isn't the issue there.
You write a dozen lines of code to do a thing. That code lives in-process. You don't touch it for years. You never have to worry about system dependencies. You never spend an additional dime on operations costs for it. You never had to develop a contingency plan for failover. You never have to worry about it suddenly breaking or a change in it's behavior that isn't directly related to a commit you made you can find with nothing more than "git blame". That's maintainability.
Using external services over bundled libraries is a decision you make on either 1. Cost or 2. Performance. If you don't have performance constraints, and you have access to a simple library someone else has developed you never choose the external service on the basis of maintainability for a given application. It's more expensive in every way.
I guess it's just hard to convey what an enabler solid, mature libraries that don't break can be if all you've experienced is the churn of Ruby and the limitations of having to farm out work to third parties because your system simply can't handle it without worrying about tying up 1 of your limited pool of 16 processes able to service requests under Unicorn for the duration of the operation. Or you're worried about scaling and cache cohernecy so you have to build a cluster of Redis servers, with custom failover scripts, additional system monitoring services to ensure it's both available and that you have a peek into it's behavior. Or you have to talk to a service to get even basic thumbnails and now you're spending 5 seconds to do what could have been done with just a few lines of code in in one second locally with no additional concerns for availability, another bill to pay, or it breaking some day because the service made "improvements".
90% of the "maintenance" problems I've seen with Ruby code can be categorized as: Scaling, Typos, or simply doing the wrong thing and talking to code or services you shouldn't have (i.e.: A SQL update to bypass validations in an offline batch processing scenario, but later on critical business logic is added and now events to trigger those side-effects are also inadvertently bypassed).
Don't validate your models beyond very basic database integrity. Don't worry about farming out services unless it's an actual organizational goal for internally developed services or it becomes a scaling or cost issue. Always favor libraries over services. Your entire stack is libraries. 99% of the code that runs your business is libraries. Services are important, but they solve a niche problem. Don't prematurely optimize for services and commit to the maintenance overhead they bring if you can't justify that with improved time-to-market or scaling because the alternative would be to roll your own. I'm not suggesting you roll your own. I'm suggesting you look on Github first unless you actually have a scaling concern.
So that was a tangent… ;-) But yeah. Maintainability is my current cause-du-jour. Because IME, the Ruby ecosystem has one of the worst maintainability track-records for time and cost of any platform I've ever worked with (and I think I'm fairly qualified to make that claim. I started with Rails v0.7, written some pretty massive open source Ruby projects, have dozens of Gems to my name and have been paid to write and maintain applications in Ruby going on 7 years now).