As a pythonista, I am a huge fan of the plumbum library as a replacement for bash. It makes it very straightforward to run a sequence of *nix commands, but you get all the simplicity and power of the python language in terms of loops and functions and so forth. These days, I do all my server management and deployment scripts with python/plumbum.
And while simple is great, the necessary features not included in OP's scripts is that I want to spin up the new instance in parallel, verify it is running correctly, and then switch nginx or the load balancer to point to the new server. You are less prone to break production and you get zero downtime deploys.
How do you deal with plumbum not being a builtin module? Do you install it system-wide? This currently holds me back from using sh (the Python lib) for maintaining my servers, especially if I need it with root.
That's not a big deal for me since I only am running a handful of servers. I install it system-wide during initial setup of a new server. Plumbum has the ability to run remote shell commands as well, so I have a script that can login to a new remote machine and do that initial setup.
I switched from Riot to Vue, and am glad I made the change.
Biggest things I noticed:
1) Getting stared with the basics is about equally easy in both frameworks. Both have a very simple and clean API and component system.
2) Vue has more advanced features -- dynamic components, easy two-way binding, watching variables, custom events, routing, etc, all of which I have used at some point as my app has gotten bigger
3) Riot seems to have more open bugs, including one major issue where even when an "if" statement evaluates as false in a template, the component still gets processed. This is supposed to be fixed in the next big release, but who knows when that will be.
4) Vue seems to be much more active -- more users, more commits, so I think it is a better long term bet.
I worked at HubSpot for many years. (disclaimer - I do not have a financial interest in the company. But I do still have strong emotional and social connections, and I was there long enough that I feel some sense of ownership for the company culture).
Remember that this article is written in order to entertain and sell books. Everything is hyper exaggerated. There are a few fair points (for instance we were very overcrowded, we could not lease new sections of the building we were in fast enough. And yeah, some of the "change the world through Inbound marketing" messaging was over-the-top and made my eyes roll). But a lot of it is either inaccurate or spun to seem bad when it wasn't (see my other comments https://news.ycombinator.com/item?id=11370077 or https://news.ycombinator.com/item?id=11370016).
For the most part, HubSpot was a normal workplace where the vast majority of the time people worked hard and did their thing. People occasionally interrupted work for fun hijinks and we did sometimes have parties after work. By packing in every outrageous story into a few paragraphs, he makes it sound way crazier than it was.
I should also add that overall work-life balance was pretty good, and the company made efforts not to be "ageist". I had both mothers and fathers on my team and they could get out of the office on time to be with their families. As we matured, we planned our fun team-building events in ways to ensure that parents could attend them. There is an implication by the author that he did not fit in because he was old, but I do not think that is a fair critique.
I didn't get a total feeling of maturity from his writing. Did you read it? Mostly low-ball shots taken at startup practices that are pretty commonplace now, primarily for their proven effectiveness. Like the fact that he was disturbed to find that Zack, being so young, wasn't an assistant but a manager. It's like the idea of promoting individuals based on results and performance, rather than age and tenure, was foreign to the author. And ironically, he displayed a lot of ageist qualities himself there. I wouldn't exactly characterize that as maturity.
This is exactly what I was thinking, I worked at a similar company and there was a lot of promoting of values and having fun but it was like most other work places most of the time. And it would be super easy to exaggerate and mischaracterise it. However I did see one or two people who resented the talk about values and saw it as brainwashing that attempted to hide the fact that we were there basically to help the founders get richer and I got a sense of that from his article.
That in a sense is of course true and you'd always be wary of such narratives and keep your own cool and detached judgements. But I don't think there's anything wrong with the "having fun" bit anyways. Surely at the end of the day only the major shareholders get super rich and you'd have to be well aware of this fact, but the fun and relaxation you had would be something nobody can take away.
I worked there, it wasn't anything as bad as what he makes it out to be. It was just shorthand for saying, "the whole is greater than the sum of the parts."
Our whole sales pitch was that we were all-in-one software. So instead of running one system for your blog, another system for your home page, another system for email, another system for analytics, another system for your contacts database, etc, etc, you would just run HubSpot, and when all the tools work together you get much better results then when they are separated. To make good on that sales pitch, we had to be constantly thinking of ways of how we could add value by integrating pieces together and making things work well together. Hence we were told to always be thinking about how to make 1 + 1 equal 3.
"In the end the Party would announce that two and two made five, and you would have to believe it. It was inevitable that they should make that claim sooner or later: the logic of their position demanded it. Not merely the validity of experience, but the very existence of external reality, was tacitly denied by their philosophy. The heresy of heresies was common sense. And what was terrifying was not that they would kill you for thinking otherwise, but that they might be right. For, after all, how do we know that two and two make four? Or that the force of gravity works? Or that the past is unchangeable? If both the past and the external world exist only in the mind, and if the mind itself is controllable – what then?"
I worked at HubSpot in engineering and I never once heard the term "graduation" in reference to a firing. Usually we just got an email saying, "HubSpot and John have decided to go separate ways" or something to that effect. If someone left by their own choice, usually they would send a "this is my last week" email and we would all go for beers on the last day. The term "graduation" was rarely used in either case. I only remember it being used in the context where an executive would say something like, "John did great work for us, he's now going to be a VP at a new startup, we want to think of this as a graduation."
> "HubSpot and John have decided to go separate ways"
That's not much better. It's very rarely mutual. Either John has been fired, or John has found another job - perhaps at a company where no one lights cleaning equipment on fire - and is quitting.
It was used quite a bit in Customer Success. It was used when I was told to leave a few days into my four-weeks' notice.
Eng was in another world, especially after the move where your team wound up in your own, separately keyed area of the building, complete with your own kitchen.
1. There was a history of heavy-weight, overly verbose frameworks. The early frameworks were over-engineered and hard to use. Lightweight frameworks in dynamic languages (Rails, django) thus took off when you they showed how you could write a blog app in fifteen minutes using only a few dozen lines of code.
2. Using non-Java JVM languages seems to always create as many problems as it solves, in my experience. First, you do not get access to any libraries with C-bindings. So as your project gets going, the probability increases that some library you want to include won't work. Also, there are all sorts of micro-frictions. Debugging support not quite working. Types not matching between Java numbers and python numbers when doing comparisons. Etc. It all adds up. If you use Kotlin, then a lot of code samples you find on stackoverflow will have to be manually converted.
3. If you go pure Java, the type system can be a pain in the neck when you are doing rapid development. Something as simple as getting a row out of the database with date field, publishing it as JSON, then getting posted back an updated version from JSON, requires a bunch of conversions and annotations to make the types all get matched correctly. Writing any sort of time-saving meta code requires a really strong knowledge of how generics, annotations, and reflection works, or else you will be beating your head against the wall.
4. Restart times are longer, and there is no REPL, so rapid iteration is a little slower.
5. I still don't think there is a web framework that is as easy to use as Rails/Django. I don't think this is the fault of the language though, and I have something in the works myself on this front...
For me (5) is the major reason. Web development with Rails/Django is so much easier and smooth compared to that of any Java/JVM based frameworks, it doesn't make sense to use the Java/JVM ones. Even a Ruby/Python novice can pick up and run with Rails/Django. You will end up building a robust, secure solution following well documented best practices and leveraging abundant 3rd party library ecosystem.
I think Play Framework is trying to achieve such usability, but I don't think it's there yet.
Play probably is the JVM world's best answer to Rails/Django, but it's neither as complete nor as frictionless. Source: I use both Rails and Play at my day job.
There are several pretty light-weight ways to make both action- and API-oriented back ends on the JVM now, even in Java. (Although I prefer different JVM languages.)
2. JNI debug is a bit of pain probably. But Java/Groovy/etc much easier to debug, compared to, say, Python
3. IMO there're no much reason to use pure Java in webdev. Only if you have well defined project, maybe already written in JVM language, that you want to optimize
4. Depends on language. Clojure have one. Groovy/Grails too.
I was never managed to debug python code :( Maybe i'm doing something wrong. Never mind, I didn't want to offend python, it's only language I like besides jvm languages.
On other hand on JVM you don't even need such line, all works out of box, w/o code modification, never had any problem. At least with java and groovy
2. stacktraces != debug. I don't actually see any difference with java stacktrace (only that it contains groovy classes, but it's still exactly same format). I mean tools for debug, like debug in IDE (look at Intellij IDEA, very powerful in debug), or JMX, take a look at VisualVM and profiling tools. There're many different tools. It's not just stacktrace.
5. Agree, not so popular that plain Spring maybe. But still, we're talking about features, right? not amount of projects on prod. Grails is pretty comparable to Rails/Django, in terms of features. Also, version 3 is too new, it requires to rewrite a lot of stuff to migrate. It takes time.
This looks like this could be a big deal. Kickstarter would be a lot more fair and more compelling if the backers were also investors, and could get a piece of the upside when helping to support development for a risky product. And it makes a lot of sense that consumers should be investors, since they often know the space better than a VC.
My immediate concern is that these rules look somewhat complicated. What will it mean to have to file a modified version of an S-1? How much will compliance cost when trying to go this route? Maybe there will be an enterprising YC company that help with Reg A+ compliance automation...?
I went through this exact situation. I joined a company when it was just the founders and me, and then we grew to dozens and then hundreds of people. As we grew, I felt these same slights: I was left out of strategy meetings, I was not mentioned on the website, managers were hired over me, etc. Overall, it felt disconcerting as more and more happened outside of my control, and without my knowledge. At first I was frustrated, then I realized I had the best of all possible situations.
Some notes:
1) If you do not have much experience scaling a team, then it is sensible for the founders to bring in someone with more experience. Scaling team requires more than just hitting deadlines. It is about recruiting, retention, recruiting, managing personalities, career growth, recruiting, managing up, communicating across teams, etc.
2) Everyone's role changes as you grow, for better and worse. For instance, early on the VP gets to have fun setting direction and designing the overall product and strategy. Later on the VP might be spending 90% of their time dealing with conflicts, recruiting, firing, managing up, etc. They may long for the day when they got to play a big role in product development. Early on as engineer, I had the benefit of being able to build an entire product by myself. Later on, the advantage was that I could take vacations and did not have to deal with bugs and outages 24/7.
3) You will have to specialize to some extent. You cannot be the jack-of-all trades role forever, no one can. If you want to eventually have a VP/CTO role, then you will need work with your VP to develop your management abilities. For instance: ask for mentoring, start reading books and articles on management, ask to have a junior engineer put in you, help out with interviews and recruiting. (Note to actually get a VP role, you will probably have to switch to a smaller startup in a few years, using your cred from this gig to get you the job.) If you want to do greenfield development, work with your VP or founder to carve out a role building out innovative/experimental/skunkworks features. If you want to do scaling and architecture do that. There are lots of ways to interesting work and build valuable skills, but you are going to have to choose a course. (In my situation, I alternated between doing experimental/greenfield features and doing scaling/rewrite work on existing tools.)
4) With regards to customer facing roles, I highly advise that your company have a policy that every engineer spend a half-day in support at least once a month. It is essential that developers stay connected to the customer, both so that you can intuitively understand how to solve their problems, and to increase your empathy and motivation.
5) Try to figure out a way to get looped-in informally to the strategic aspects of the business. Make some sort of effort to have lunch or beers with a founder once a quarter. If you have 1:1's or have a wiki where decisions are discussed, then that can be a good thing. The execs understandably want to keep management and strategy meetings to a small number of people, otherwise the meetings suck. But finding a way for you to informally connect and give your two cents can be valuable both for you and the execs.
6) If you want to raise your profile and get your name known, use whatever leverage you have to get some favors. Ask to have yourself put on the web site as "Founding Engineer." Figure out a way to have the founders to introduce you to useful people, and to help you get into some of the more prestigious invite only events, whatever they are in your area. You have to use judgement and be diplomatic, because you might also lose out on advancement if you are seen as angling for a quick exit.
7) Generally, I would recommend sticking with the company as long as it is on an upward trajectory (unless you have a compelling alternative). You will learn a lot as you go, and your reputation will increase with growth.
Eventually I realized that I had the best of all worlds. Why does one want to be a VP? Usually money and status. What sucks most about being a line-level employee? Lack of agency/control. But in many ways it is less fun to be a VP, than to be a high-status engineer, who has enough sway to avoid micromanagement, enough credibility to control his or her own destiny, who can spend their time working the craft that they love. As engineer #2, you get status by virtue of your early employee number, and hopefully and you will get good money from equity stake (if not, then that is truly unfortunate). So hopefully you get the money/status benefits of being an executive, while still getting to work your craft, and still getting to stay in a peer relationship with your fellow engineers.
"For any significant piece of logic, it ends up living in a class on its own, with its dependencies injected either via constructor parameters or method parameters."
And I was worried I was the only one who thought this was crazy!
In most python frameworks, like django, when you want to call some service, you import some static class or singleton. It is simple and straightforward. If the framework wants to allow you to swap in different implementation classes, then it will define a singleton or static class with a clear API that then dispatches to the specific implementation class based on your global settings. Or, if you want to override the default implementation on the spot, you can just invoke the implementation class you want directly.
So in django, I just do:
from django.core.cache import cache
cache.get('my_key')
Voila! That's all the code I need, and it works great. I can easily swap in memcached or a file cache or a local memory cache or whatever. It is straightforward and easy to debug. If I am wondering why the wrong implementation service is being used, I can usually step through with a debugger right at the point it is being called and figure out what is going on. If you I am writing tests, I either use different settings or monkey patch the static class in my setup and tear down functions.
In most java frameworks, your classes are supposed to either accept the service via a constructor, or have it injected into your class via Guice or Spring. This adds a whole new level of complication and verbosity, and means things break far away from when you are using them. I know people swear by dependency injection, but I really don't get it, I have never found it to be a better pattern than the django pattern.
Python doesn't do anything differently. Your line of code there is accepting the django.core.cache.cache object as the 'cache' parameter to its containing module's global namespace, 'injected' by the module loading system.
Java doesn't have that loading system, so there is a small cottage industry of frameworks that provide its valuable features. None of them can rely on a language-specified import system and global namespace to which things can be added, which is why they get parameterized one way or another.
Breakage from faraway places can happen in either system, as far as I can tell. It's kind of inherent in the abstraction.
Were the paying customers actually using it? Did they love the product (ie, would be a 9 or 10 on an NPS survey)?
If yes, then you should have worked more on sales and marketing.
If no, then you built the wrong feature. Blindly adding a collection of features won't help. You need to figure out what the one feature is that will make customers rave about the product.
The core problem might be that your product ideas were "pretty good" ideas and not "very good" ideas. "Pretty good" ideas are deadly, because they are just good enough to suck you in, but not good enough to make a product that customers rave about, and thus not good enough to make with a product that is easy to market or spread by word of mouth.
And while simple is great, the necessary features not included in OP's scripts is that I want to spin up the new instance in parallel, verify it is running correctly, and then switch nginx or the load balancer to point to the new server. You are less prone to break production and you get zero downtime deploys.