Local Covid-19 Death Rate

Another interesting way to look at the local covid-19 stats for San Mateo County CA is the death rate by age. This virus is showing a dramatically different lethality by age bracket. I know there are researchers looking into this and there is a lot of data about comorbidities, but I don’t know for sure if age is simply a very good proxy for comorbidity.

What this chart tells me is that we HAVE to get this virus under control for the long term. If these death rates stay constant, then after a few years there just won’t be many people left over 70 years old.

Vaccinations are working

I was curious this morning and decided to take a look at my county’s stats for Covid-19. Right now they’re allowing 65+ and certain groups to get vaccinated, although we’re really excited that on April 15th they’re opening it up to all adults.

I charted the percentage distribution by age of the historical numbers vs the last 30 days. You see a significant decrease in the population of people that have been fully vaccinated. I’m really hoping that as this trend continues across the population we’ll get rid of this virus.

Regulating Online Speach

There’s a very active discussion happening right now about free speech online after the removal of Trump from Twitter.

The least informed arguments state that this is a violation of the 1st Amendment for the banned people. This is obviously not true as the 1st Amendment applies to the power of the government and not private companies.

The more nuanced discussion moves on to accepting that these companies should be allowed to moderate. There are many examples of threatening and violent speech that require moderation. However, there is no clear standard on where that line should be and who should make that determination. Twitter’s current policies have been confused. They didn’t apply a single consistent moderation policy to all users. Twitter made the case that the United States President had newsworthiness that forced them to keep him on the platform even if they had to label his tweets.

David Sacks* has made the case that the oligopoly of Big Tech companies like Twitter, Facebook, Google, Apple, and Amazon are so large that when they apply content moderation policies and squelch someone’s voice that they are functioning as a de facto government institution and should be held to the 1st Amendment bar. He argues that the 1st Amendment was created when the idea of the internet didn’t exist. That the founders couldn’t have imagined it and that the town square is now the equivalent of your Facebook or Twitter timeline.

Sacks just tweeted that “My content moderation policy is the First Amendment. What’s yours?” The 1st Amendment, as a standard, is a horrible idea. Anything is allowed as long as it’s not so heinous or threatening that it would require us to charge you with a crime because of the words you used. No civil, productive discussion could flourish under these rules.

At the founding of this country, we had the concept of different public and private spaces in a town. Each of these spaces had different rules for acceptable behavior for the people using them. If you are unruly in a restaurant, you will be asked to leave. If you are screaming and shouting, you will be kicked out of the public library. If you don’t dress appropriately, you won’t be allowed into a fancy restaurant.

None of this means that the government is forcing you to dress a certain way or to only whisper. But it does mean that you are required to abide by the rules of a location to use that location. If you want to get together and play music with some friends, you need to find a suitable place. The 1st Amendment doesn’t mean that you can roll up anywhere and do what you please.

I believe that this relates to the online free speech discussion similarly. Each location is owned and operated by a company, and they’re free to decide how they want to moderate. If you’re not happy with how those decisions are being made, then you’re free to spend your time elsewhere. The argument that Facebook is so large that it should behave like a government is wrong. The argument should have been that we should foster alternative locations.

If a restaurant is so popular in a town that it puts all other restaurants out of business, that doesn’t mean that it now needs to function as a government service and serve food that everyone agrees with. If you’re not happy about the menu choices, you should start another restaurant and compete with it. Of course, you’re not guaranteed that your new restaurant will be very popular or profitable, but you’re free to start and run it.

Sacks has pointed to the case of Parler.com as an example of starting your own restaurant not working, but I don’t think the argument stands up. Parler was able to create an app and got a large number of people to sign up. However, they continued to distribute heinous speech and were very loose in moderating it. We live in a community, and Parler relied on other vendors to provide their service. When it became clear that they weren’t going to moderate the content, the vendors decided to cut their business associations. No one banned Parler from existing, but others were not required to help them out either.

If you don’t like that AWS won’t support Parler, then don’t use AWS. If you don’t like that Twilio won’t support Parler, then don’t use Twilio. Create your own competing services and back up Parler. I don’t think there are many people that will be leaving AWS because of the decisions they’ve made.

Finally, Sacks argues “If your views are preferred by tech oligarchs, you can instantly get distribution to millions. If not, you can stand in the street yelling like a lunatic. No undue influence over our democracy there“. I agree that we have a problem in that a tiny number of companies have so much power, but I have to disagree with the remedy. I believe that just as we have many choices for offline locations, we need more varied locations to gather online. But, no company is an island unto itself. We all have to work together as a community.

*I don’t mean this to come across as if I’m attacking David. I actually think he’s thought long and hard about this and is trying to have a reasoned debate. I chose his arguments as some of the most reasoned conservative arguments that I’ve seen.

Bringing back the blog

Hiking with the kids

It’s been a while.

Life has been crazy.

My focus these days has been on the kids and making the most of their education while we’re all trapped sheltering in place. It’s a very interrupt-driven environment, which means that it’s tough to sit and focus on development work. So, I figured I’d do a little easy sysadmin work and get the blog back in decent shape.

This site has been living on a t2.small AWS instance for years. I had used a Bitnami installer to package up a whole WordPress installation. It was super easy to set up but was getting harder to maintain. The VM was running Centos 6, which is just prehistoric these days, and with apache, PHP, WordPress, and MySQL all bundled, it was hard to make sure that everything was up to date.

So, I broke everything back apart and did clean installs. Got the OS upgraded to the latest Ubuntu, which is dramatically easier to keep up to date. I moved off of Mysql and instead used AWS RDS Aurora. Did a clean vanilla install of WordPress.

One last thing that I had wanted for a long time so that I could take snapshots of the server and run multiple instances if necessary, was to move the media libraries and other files to S3 and use a CDN. This turned out to be easier than I had expected. Just required 2 CloudFront distributions for all of the sites hosted on this installation.

Now, I’m ready to get back into the habit of posting some thoughts and ideas. Not that I think anyone will read or care, but I’ve got to keep practicing writing.

Configuring a spring application to use https behind an ELB

I have a couple of sites that run on AWS and take advantage of Elastic Load Balancers to handle proxying to servers in a private VPC as well handling https security. While CloudFront distributions can be configured to upgrade requests to https if they come in as HTTP, I haven’t found a way to configure ELB connections to do the same. What I wanted is for the ELB to listen on both port 80 and 443 and if a connection comes in on 80, then to redirect to the same request on 443. This way if a user just enters the URL into their browser, they’ll automatically be upgraded to https even if they didn’t remember to specify it.
It’s fairly simple to accomplish this with an Interceptor. Create a class that will handle the redirects.
 

@Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
  private static Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class);
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String proto = request.getHeader("X-Forwarded-Proto");
    if (!Strings.isNullOrEmpty(proto)) {
      logger.debug("Found proto: {}", proto);
      if ("http".equalsIgnoreCase(proto)) {
        StringBuffer redirectString = createRedirect(request);
        logger.debug("Redirecting to {}", redirectString);
        response.sendRedirect(redirectString.toString());
        return false;
      }
    }
    logger.debug("No proto header found");
    return true;
  }
  private StringBuffer createRedirect(HttpServletRequest request) throws IOException {
    StringBuffer result = request.getRequestURL();
    result.insert(4, "s");
    String queryString = request.getQueryString();
    if (!Strings.isNullOrEmpty(queryString)) {
      result.append("?");
      result.append(queryString);
    }
    return result;
  }
}

Since encryption is handled by the ELB and all traffic arrives at the server as HTTP we have to rely on the x-forwarded headers to know if we should redirect the request back to a secure page.
Then I have a config class to load the Interceptor.

@Configuration
public class WebMVCConfig extends WebMvcConfigurerAdapter {
  @Autowired
  private SecurityInterceptor securityInterceptor;
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(securityInterceptor);
  }
}

This Interceptor is specific to the x-forwarded headers that ELBs will send to the backend instance.
 

Hiring for culture fit can have unintended consequences

An interesting post on “culture fit.” I’ve been catching up on the SAASTR podcasts, and a lot of the interviewees sound like they’re falling into this trap. I agree with Matt’s assertion that by trying to hire people that you would want to hang out with, you will end up hiring a lot of people that look like you. Instead, you should focus on culture agnostic characteristics:

  • Are they kind and empathetic?
  • Do they care about their work?
  • Do they have good communication skills?
  • Do they have good self-management skills?

Finally, also look for “Do they bring a valuable new perspective?”

Terminal hack to make logging into a cluster easier

I’ve been looking for a way to make it simpler to quickly login to all nodes of a cluster from a mac terminal. Discovered a small npm module that helped me do it called ttab. With this npm module I can then write a bash script:

#!/bin/bash
TYPE=$1
rs6 () {
ttab -w ssh bryan@example1.com
ttab ssh bryan@example2.com
ttab ssh bryan@example3.com
ttab ssh bryan@example4.com
ttab ssh bryan@example5.com
ttab ssh bryan@example6.com
}
if [ “rs6” = $TYPE ]
then
rs6
fi

This will open one new terminal window with 6 tabs all logged into the different servers.

Spring Boot with JSP and React Template Application

Awhile back I was playing around with moving some personal applications to use spring boot. There are a lot of really nice aspects to this project. You get a whole lot of functionality without having to write boilerplate code.

  1. Executable jar file.
    1. packages entire application as a single executable file.
  2. Service Support
    1. link to your executable jar from /etc/init.d and you get full Linux service support (start, stop, restart, status)
    2. logs go to /var/log/{application name}.log
    3. PID status support in /var/run/
  3. Embedded web container
    1. tomcat or jetty is upgraded with your spring boot version, so you don’t have a separate set of binaries to maintain.

The biggest downside that I could see was that JSPs are not supported out of the box because of a tomcat issue. Spring boot is perfect for developing REST microservices but somewhat limited as a general purpose web application replacement. You need to convert your display code to use Thymeleaf templates, which could be a significant amount of work.
I came across a workaround to get JSPs working as expected. It involved moving files out of the /WEB-INF/ directory and putting them in /resources/META-INF/resources/WEB-INF/. It’s a little weird, but when you do it, everything works as expected. You’re even able to use things like JSP tags just as you would have before.
Another thing that I’ve been spending time thinking about is how to integrate a Java development project with a current Javascript setup. Maven works as well as anything for a large multi-module structure, but how does the Javascript code incorporate? There are a lot of different options. I wanted a build pipeline that would allow you to use the more popular Javascript tools, not break for non-Javascript developers, and allow fast iteration of Javascript changes (doesn’t require a full ‘mvn clean package’ to see changes).
After all of this experimentation, I believe I’ve found a good balance of tools for both Java and Javascript developers. It uses Spring Boot with full JSP support as a base. Gulp and Webpack for the Javascript build pipeline. Has a development mode that uses the Webpack dev server to iterate quickly. It also includes support for development with React, so you can play with the cutting edge of developing web applications.
I’ve done all of the fiddlings with different settings and created a working template application.  Check it out and let me know what you think.