Heroku changing up dyno pricing

Heroku is trialling new pricing levels for their dynos. Here’s the verbatim text they gave:

Free – Experiment in your own dev or demo app with a web and a worker dyno for free. Sleeps after 1 hr of inactivity. Active up to 12 hours a day. No custom domains. 512 MB RAM.

Hobby – Run a small app 24×7 with the Heroku developer experience for $7/dyno/mo. Custom domains. Run a maximum of one dyno per Procfile entry. 512 MB RAM.

Standard 1X, 2X: Build production apps of any size or complexity. Run multiple dynos per Procfile entry to scale out. App metrics, faster builds and preboot. All Hobby features. 512MB or 1GB RAM. $25 or $50/dyno/mo.

Performance – Isolated dynos for your large-scale, high-performance apps. All Standard features. Compose your app with performance and standard dynos. 6GB RAM. $500/dyno/mo.

Continue reading Heroku changing up dyno pricing

Fun networking stories: connecting three machines away via SSH

We had a hardware unit that was Ethernet enabled. To configure and manage it, the vendor provided us with a Windows program that, given the unit’s IP, could establish a TCP connection to the unit’s port 3300 and do all of its fancy management things.

The only problem was, the hardware unit was a hundred miles away on a private subnet at a client’s building, and the only thing that could directly talk to it was Linux computer A that we installed alongside the unit. We had the foresight to install Hamachi on computer A, and my own Linux computer B here also had Hamachi. My clunker Windows laptop C that could actually run the software was hooked up directly to computer B via Ethernet.

So, computer C had the Windows program and could talk to computer B via direct Ethernet. Computer B could talk to computer A via the Internet using Hamachi. And computer A could talk to the hardware unit via its local VLAN.

C -> B -> A -> hardware unit

The transitive property of hooking-up-computers states that if C can talk to B and B can talk to A, then C can talk to A. But how?

Well, when you only have SSH, every problem looks like an SSH connection.

  1. Computer B connected to computer A and established an SSH tunnel. The SSH tunnel forwarded B’s localhost:5000 port to A’s hardwareunit.local:3300. computer-b$ ssh -L5000:hardwareunit.local:3300 computer-a.local
  2. Computer C connected to computer B and established an SSH tunnel. The tunnel forwarded C’s localhost:3300 to B’s localhost:5000. computer-c$ ssh -L 3300:localhost:5000 computer-b.local
  3. Windows program on C connected to C’s localhost:3300, which actually goes to B’s localhost:5000, which actually goes to the hardware unit’s port 3300 via A.

Yes, everything was passed along via two SSH connections in a row, but it worked quite well, and it will save us from driving down to the client in the rare case that we need to do this again.

Workaround for HipChat on Linux: “can’t find build id”, “HashElfTextSection”

The new version of HipChat added support for video and screen-sharing. It also introduced the new requirement of OpenGL 2.0. On my computer, HipChat would crash on startup with repeated messages of

can't find build id
can't find build id
can't find build id
can't find build id

I wasn’t going to try video chatting on my old netbook anyways, so there’s no reason I needed hardware support for rendering text and emoticons.

First, get your system’s OpenGL info by running `glxinfo | grep OpenGL` and find your version string:

Continue reading Workaround for HipChat on Linux: “can’t find build id”, “HashElfTextSection”

OpenStreetMap provider CloudMade shuts its doors on small users

(Original email at bottom.)

CloudMade, a company selling mapping services (many based on OpenStreetMap data) that competed head-to-head with Google, let its users know that as of May 1st, they’ll stop serving anyone who’s not on an enterprise plan. This is rather sad, because they were one of the main alternatives for custom OpenStreetMap tiles.

Their map tiles definitely left something to be desired. The OSM data that they were using seems to have been last refreshed around the time Steve Coast left (maybe that’s a wee bit of an exaggeration) and the rendering was never very polished—ugly icons and labels getting cut off on tile boundaries. But for $25/1M tiles (with the first 500k free), could you really complain?

CloudMade even listed Steve Coast, founder of OpenStreetMap, as a co-founder. Steve Coast left in 2010, and it was hard to tell what the company was trying to become. Now, we see that they’re gunning for enterprise services, along the lines of Navteq and TomTom. Instead of dealing with small fries like us, they’re apparently focusing on bigger deals like providing data for hardware and consumer electronics.

Maybe they just got tired of my emails to support asking why this or that was broken or when they’d update their data. Now, we’re left with almost no options for custom hosted OSM tiles. MapBox is one popular choice, but their online map customizer is elementary compared to CloudMade’s (and CloudMade’s was not super advanced). MapBox also have stricter terms of how their map tiles can be used. No proxying/caching of MapBox tiles is allowed, for example, especially since they charge based on usage.

CloudMade helpfully gave some alternative providers for us small fries to switch to. Still, one less provider means more risk when using a hosted provider. For example, who are we going to turn to when MapQuest decides to shut off its routing services?

Here’s to hoping people will step up and fill the gap that CloudMade is leaving. Us little users who will only pay a couple hundred dollars per month will then have somewhere else to go.

This is what came through today:

Hi [username],

We want to let you know about some changes we’re making to the CloudMade APIs. As of May 1st we’re switching to an enterprise model that supports the medium to large sized users of the CloudMade APIs. As part of this transition we’ll stop serving Map Tile, Geocoding, Routing and Vector Stream Server requests coming from your API keys below as of May 1st, unless you take action.

Your active CloudMade API keys are: W,X,Y,Z

If you wish to continue using the CloudMade services after April 30th you’ll need to upgrade to an enterprise plan. Enterprise plans are available for customers with 10,000,000 or more transactions per month. The plans include dedicated hosting, custom SLAs, 24×7 support from a named customer support representative and custom data loading. You can find out more about upgrading and request more information on the Web Portals page.

If your monthly usage is less than 10,000,000 transactions, or you don’t wish to upgrade to an enterprise plan, you should take action to update the app or website that’s using the CloudMade API keys shown above to use an alternative provider. There are a number of alternative providers of Map Tiles, Geocoding and Routing services based on OpenStreetMap data, for example:

– Mapquest (Map Tiles, Routing, Geocoding)

– MapBox (Styled Map Tiles)

Thanks for using CloudMade’s APIs over the past months and years. If you don’t switch to an enterprise plan, we wish you a smooth transition to the new service provider you choose.


Disclaimer: Nothing written here represents my employer in any way. I am/was a mostly satisfied user of many OSM-based services out there, including MapBox, MapQuest, and CloudMade.

tuntuntun – Combine Multiple Internet Connections Into One

GitHub repo: https://github.com/erjiang/tuntuntun (proof of concept status)

I was trying to play Minecraft by tethering over a Sprint data connection but was having awful random latency and dropped packets. The Sprint hotspot seems to only allow a limited number of connections to utilize the bandwidth at a time – a download in Chrome would sometimes stall all other connections. This was a huge problem in Minecraft, as loading the world chunks would stall my movements, meaning that I could teleport somewhere and die to an enemy by the time the map finished loading.

I’ve been seeing the idea of channel bonding here and there for a while, and it always seems like a cool idea without any popular and free implementations. Most of the approaches, though, were restricted to assigning different connections to different network interfaces. Essentially, a connection to YouTube might go over one link, while a software download might go out another. This works OK if you’re trying to watch YouTube while downloading updates, and it works great for many-connection uses like BitTorrent but in this case, I wanted to create a single load-balanced connection. So, I created tuntuntun.

Somewhat like a VPN

tuntuntun diagram

This requires the help of an outside server to act as the proxy for all of the connections, because most current Internet protocols require connections to originate from one address. The idea is to establish a connection to the proxy using a custom protocol that allows data to be split between two links. Tuntuntun works by encapsulating IP traffic in UDP packets, and does this in userspace using tun interfaces. A tun interface is a virtual network interface that has a userspace program as the other end. This means that any packets sent to the tun are read by the userspace program, and anything that the userspace program writes to it becomes “real” packets in the kernel.

Continue reading tuntuntun – Combine Multiple Internet Connections Into One

Googling for bugs: hundreds of date-formatting mistakes

Here’s something really easy to screw up:

echo date("Y-m-d H:m:s");

Spot the mistake? The “m” format code can only mean one thing, which is “months”, not “minutes”. Yet, when you’re writing code in a hurry, it’s so easy to quickly write this code and assume it works. After all, it raises no errors or warnings, and always generates valid datetime strings. It’s just wrong.

Googling for ‘site:github.com “Y-m-d H:m:s” php’ returns hundreds of examples of mistakes. I tried to fix a couple instances but realized that there’s so much abandoned code on Github that it would’ve been useless.

This is a prime example of something that static analysis could warn about: just look for “H:m:s” or “h:m:s” in the first argument to date. This mistake isn’t limited to PHP, of course, as this Java example shows.

Have you ever been computer illiterate?

If you’re like most hackers, you’ve spent so much time on the computer that the jargon and lingo have become natural. You instinctively know where the OK and Cancel buttons are, and get upset when they’re switched around for no apparent reason. You scan dialog boxes and make the right decision in a second, because who hasn’t seen “Do you want to set Firefox as your default browser?” a million times?

We are perplexed when users click through confirmation windows without a second thought. We sigh when someone doesn’t know where to find their terminal emulator. We become frustrated when people complain about poor performance but can’t even tell us whether they’ve maxed out their RAM and have swapping.

Look at these words! We’ve churned out so many abbreviations and neologisms that other developers can’t even understand us! But what about our users? What if they’re not computer professionals with 10+ years of Internet experience? What if they don’t know what we’re talking about? Or what if they’re using your product in something other than their native language? Why aren’t our users like us?

Try this. Switch your software into a language that you don’t know very well. If you took Spanish throughout high school or a couple years’ German in college, switch your computer to that. It’s very easy to do in OS X and iOS, and almost as easy on Ubuntu. Google products can be switched by adding the “hl” param to most Google URLs. For example, “hl=ja” switches the page to Japanese.

Just drag’n’drop another language to the top.

It’s a completely different experience.

Don’t just switch back after a day. Force yourself to use your computer in another language. After all, there are millions of people who simply can’t switch their computer to their native language. Use your now-alien computer, and you’ll find your habits changing.

Your eyes don’t immediately zero in on the correct list item any more. You avoid using the menu bar until you know you have to, and when you do, you’re still guided by a spatial-positional “feel” of where things are. And if it’s a rare need, like changing your accessibility settings, you sit there and slowly read each menu item until one of them vaguely sounds like what you’re looking for.

And it’s not just an issue of knowing words. You might know the words, for some superficial meaning of the word “know”, but when ordinary words are applied to computers, it often takes mental processing to understand their new meaning.

When you click “Cancel” in a dialog box, what are you cancelling? Is it cancelling in the same sense that you would cancel a reservation or a plane ticket? (We are all guilty of genericizing “OK” and “Cancel” as the default dialog-box buttons.) When I see “Ventana”, I think of a big hole in my wall filled with a glass panel. I can’t help it—that’s the meaning I learned—and it takes a second or so to recognize that that’s where I should go to find a list of my terminal instances. And when I first saw “終端”, which could be defined as “end extremity”, it was only by recognizing its icon that I knew it meant “terminal”.

Why would expect people to know that “terminal” means that little window with monospace text and funny symbols? We don’t even think to ourselves that historic terminals were the endpoints for mainframe communications.

So notice how your usage changes in an unfamiliar environment. You’re afraid of clicking words you don’t understand, because it might be even harder to undo your changes (e.g. setting your keyboard to “드보락”). When you don’t know how to get the functionality you need, you’d rather work around the problem or Google for the answer, because you can’t skim long drop-down menus very quickly. And textual documentation is useless, because the time and energy it takes to decipher the documentation is more than you’re willing to spend on your problem anyways.

Suddenly, customizing your computer becomes a chore, made worse by the nagging uncertainty of being able to remember how to reset those options. You notice subtle differences in localization between vendors as well—why is it that you some times 复制 and other times 拷贝 to send the selection to your system clipboard? You tend to stick to applications you’re familiar with, because you’d much rather get things done than spend so much time figuring out a new interface. You can feel your textual comprehension speed drop by a factor compared to what you’re used to.

And when you’re not sure, you rely on visual cues to confirm your guesses. The System Preferences icon to change your language back might be “言語とテキスト”, but it looks especially promising because it has a wavy UN flag as its icon. (A globe or a couple characters from different character systems would be great too.) The default options in dialog boxes, along with their positions, become important too, because you don’t feel like reading the actual message, and you’re likely to pick the rightmost or highlighted option anyways.

You like things with fewer options, because it takes less time to read them all, and it means fewer chances to mess something weird up. Visual layouts help with understanding things, because you can draw analogies to what you know. And it’s not always obvious which things are action widgets that you can click on, especially if they’re not styled like a button (I’m looking at you, Android).

So go ahead, change your system language and use it for a month. You might be surprised at what you’ve taken for granted.

Dreamhost is so 2004

Today marks my final move from uncool, mainstream shared hosting to the fantastic world of pay-what-you-need technology mash-ups.

Shared hosting…

I used to have shared hosting at Site5. They were OK. I really can’t complain much except that their dashboard functionality for hosting multiple domains on one account seemed archaic. I signed up almost exactly 5 years ago on their The Five Dollar Web Hosting Deal, which offered seemingly huge allocations of 55GB of disk space and 5TB of bandwidth. The plan has long been discontinued and Site5 followed the rest of the industry towards “unlimited” shared hosting, but I never “upgraded” because I never hit those limits and the newer $5 plans couldn’t host multiple sites. Site5’s interface got slicker and their servers got stabler, but I eventually wanted to go beyond ordinary shared hosting.

Shared hosting has been such a smoke-and-mirrors industry designed to lure in inexperienced webbies with promises of “Unlimited!” and “One-click blogs!”. Sure, for many people, it’s perfectly fine for putting up some information about the local Habitat for Humanity or chess club, but even then, wouldn’t a free Tumblr or Google Sites account be just fine? Regardless, I decided to get more hands-on with my new setup.

Continue reading Dreamhost is so 2004

HTML <legend> tag is broken in WebKit

All I wanted was for a legend tag to fill up its box horizontally, much like an h1 or div does by default. Apparently, legend tags are special and don’t follow the same rules as other tags in WebKit, and what I wanted to do was simply impossible. Since I wasn’t the one to choose to use the legend tag (it’s a CakePHP default), I simply replaced all instances of it with <div class="legend"> and went on with life.

Here’s an example in which the same display: block style is applied to an h3, a span, and a legend tag, each sitting in identical divs.

Gecko renders the legend tag as a block element correctly, and it fills up the div.

WebKit does something special about the width, and so it fails to fill up the div.

Given WebKit’s lineage, it’s not surprising that KHTML does even worse at the exercise.

Try it for yourself: legend width js-fiddle. Other people have had similar issues as well: StackOverflow: Cannot add margin to Legend element in Safari & Chrome.