Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: essay

  • Name Collisions

    Name Collisions

    Many many years ago I played MUSHes. One of the games was PernMUSH (which apparently is inactive now). PernMUSH took place on the world of Pern, and you had the chance to be a dragon rider. Which was kind of the Thing to Be ™. One of the ‘quirks’ of the game was that every character had to have a unique name, and so did each dragon. When I started playing, I didn’t really understand this. Today I know that it’s because of name collisions.

    A “name collision” is a problem not solely endemic to computers, but it comes up there an awful lot, whereby you must have a unique identifier to know what each ‘thing’ is. For example, in WordPress every post has two unique identifiers. It has a post ID, which is a number given to the post when it’s stored in the database. If you use ‘ugly’ permalinks, you’ll see this as example.com/?p=123 – that 123 is the post ID. But if you use pretty permalinks (like I do here — example.com/my-cool-post/) then you have to have only one ‘post’ with that name.

    You, literally, cannot have two posts with the same ID or name. Makes sense, right?

    On PernMUSH we had everything have a unique ID as well as a unique ‘nice’ name. But then when dragons were introduced, you had to give them unique names as well. This was not for frivolous reasons nor pretty special snowflake ones. While it was perfectly understandable to have a hundred rooms named “Bedroom,” the code for the dragons allowed them to all talk to each other and send private messages. They were, basically, our cell phones. Dragon Ath had to be able to talk to dragon Bth, and in order to ensure that worked properly without everyone having to type dtu #12724=message we had to have the code written such that someone could type dtu bth=message and that meant each name had to be unique.

    This would have been fine and dandy as it was except for one small problem. PernMUSH wasn’t the only MUSH based on Pern. There was also a game called SouCon, which took place on the Southern Continent. And transfers between the games were allowed. This added in a wrinkle that now PernMUSH and SouCon had to be sure that everyone on both games had a unique name and dragon name.

    It was quickly determined that they wouldn’t bother with human names. If J’cob on SouCon came to visit PernMUSH, which already had a J’cob, then SouCon’s J’cob would use a different name like Jy’cob. But for whatever reason it was decided that the dragon names on both games were going to be unique. Thus the “All The Weyrs List” was created. That list (which still exists at dragons.pernmu.com ) was a mostly honor system site where you would email in your ‘hatching records’ with who’d impressed and to what dragon and what color and who were the parents. The list would be updated. Then the next time anyone had a hatching, they’d search that page for the dragon names they wanted to use. If the name was there, then then couldn’t use it. Done.

    Of course this wasn’t perfect. Anything based on the honor system is bound to have a few bad eggs. After 10, 15, 20 years, the ability to give people the name they ‘want’ starts to chaff against the tacit agreement not to repeat a name. At some point, I know some games gave up and let people have whatever name they wanted, and transfers could cope.

    What does all this have to do with anything?

    On the WordPress.org servers, where we list all the plugins approved by the team, each plugin has a unique slug that cannot be changed. I have a plugin called Impostercide, which has the slug of impostercide and it’s the only one. No one else can submit a plugin with that name. For the most part, this worked fine. If someone else wanted to make a plugin with that name, they were free to do so but it just wouldn’t be on WordPress.org and that was okay.

    Then we shot ourselves in the spirit of making life easier. Today WordPress updates your plugins and themes by using an API that calls back to the wordpress.org servers. That API check sees if Impostercide on your install of WordPress is older than the one on wordpress.org and, if so, alerts you to update. You press a button and your plugin is updated. It’s magic. It’s gold. It’s great. If you’re that person who wrote your own plugin, not on wordpress.org, you can hook into the update code and have it update from other servers. It’s brilliant.

    Except what if you’re that person who has their own plugin named Impostercide? The obvious answer is that you can just rename your folder and off you go. That doesn’t fix the thousands of people who just upgraded themselves to my version, though. They’re having a bad day. Also what if someone submits a plugin called impostercide-two? Now you have the same problem all over again. Other people will tell you to bump the version to something the real Impostercide will never use. But again, that doesn’t hold up since what if Impostercide does?

    The actual fix is to tell WordPress not to check for updates for that specific plugin.

    The awesome Mark Jaquith posted about this in 2009. You can code a plugin to tell WordPress to not check for updates for it. This does put the onus on people who are writing the plugins not hosted on wordpress.org though, which is and isn’t fair. There’s a movement to allow a new plugin header to prevent these things in trac ticket 32101, which boils down to the idea that if those non-org hosted plugins can flag themselves as ‘I’m not from .org’ then the API stops trying to update them.

    I think that it would be a good idea to have an easy way for people to flag their plugins as not being hosted. The alternative would be an honor system method, where everyone registers their plugin slugs and all submissions to wordpress.org is checked against that. But that falls apart quickly the day one person forgets to do it. With a way to easily kill the API check, we can allow non-org hosted plugins to very simply protect themselves, and their users, from being stomped on.

    As for the risk that someone might edit their own locally installed copy of Jetpack to have that header because they’re tired of updates, well, we can’t stop you from shooting yourself. I just hope people are smart enough to understand that you don’t edit core and you don’t edit plugins and you don’t edit themes. You make child themes, you use other plugins, and you use filters and hooks.

  • Rant: Gmail Contacts

    Rant: Gmail Contacts

    It’s been a while since I’ve gotten to have a good ol’ rant in on tech!

    I use Gmail in the browser, like my friend James. It’s meant to be used there. I’ll use it there. But I often get emailed new contact information, and I want to add it to Google Contacts. Here’s the workflow.

    I open the email and click on the ‘add contact’ button.

    Google - Add vcf to contacts

    There’s often no response at this point. The page sits there and I don’t see anything telling me to go to another page. Eventually the browser takes me to a new page in the same screen where I now have a new contact group with the name “Imported DATE” and one user (or possibly two if I clicked, saw no response, and clicked again):

    My new google contact group and my new user(s)

    At this point, I have to click the find and merge to get them back down to one. Then I click what groups I want the new user to be in. Of note, you must press the “Apply” button:

    I have to press Apply to add Obenland to WP

    No ajax here.

    Yay! Obenland is in WP!

    But what about that group?

    I have to delete the group

    Now some of this I can do from the list user screen, but I still have to go to contacts, mess with it, and then delete the temp group. No ajax. No way to add just from within mail. No way to open in a new window.

    It’s just crap.

  • Make or Break Yourself

    Make or Break Yourself

    How you react to adverse situations is what makes or breaks your business, not the fact that you had one in the first place.

    Taylor Swift recently penned an open letter to Apple Music. To Apple, Love Taylor lets us all in on a fact of the new Apple Music (their streaming service, coming soon for free for 3 months) that a lot of us didn’t know.

    I’m sure you are aware that Apple Music will be offering a free 3 month trial to anyone who signs up for the service. I’m not sure you know that Apple Music will not be paying writers, producers, or artists for those three months. I find it to be shocking, disappointing, and completely unlike this historically progressive and generous company.

    Three months where we get free music is great, but the cost of that free music was astronomical. As Taylor points out, it doesn’t hurt her, she has money. But the indie people will be terribly hurt by this, to the point that many of my indie friends pulled out of the trial too.

    Apple kowtowed in under 24 hours from that post. Eddie Cue (who’s the Apple mogul in charge of this project) replied on Twitter:

    I see a lot of people take criticism in some pretty appalling ways. I’ve been threatened with legal action for not deleting a one-star review of a plugin on WordPress.org. I’ve been vilified, called a Nazi or worse, and had my reputation blasted because I stood up for a user who didn’t like a product and left a bad review. I get insulted daily because I tell people “If someone misunderstood what your documentation said, you need to review your docs and consider updating them.”

    I’m glad I have a thick skin, because some days the things people say and accuse me of would make me cry. Sometimes they do, and those are the days I walk away and let someone else handle that person, or just take a break.

    In general, I believe in the inherent capability of goodness in humanity. I assume good faith. I presume that people who are leaving reviews aren’t generally doing it to attack me personally, but because they’re having a terrible day. Maybe they’re having the worst day of their life. And I, as an experienced support tech, know that they’re pretty much always going to be irrational.

    That’s the thing. People aren’t usually intentionally misleading, nor do they plan to make my life miserable. They’re having a bad day and it’s perceived to be my fault, so I’m sorry, but let me try to understand things better. How I reply to them depends on how they come to me with their issues, though. If they say ‘it’s broken!” (a common complaint, right?), I tell them I’m sorry and ask them if they can explain what, exactly, is broken. I may spend time clarifying with them “Do you mean X?” and I may ask “Why are you trying to do Y?” so I can understand the big picture.

    And then… those people who come at me and say “This person is lying and gave me a bad review!” I’m often inclined to side with the users, since a bad review is something that makes people overreact. But that doesn’t mean I dismiss the complaint out of hand. I check if the reviewer is a fake account (we have ways), and I check their history and their information and validate they’re real people before I reply. If they’re fake, I remove the reviews. If they’re not, I leave them be.

    Leaving them be is where most (if not all) of the hate comes from. You see, leaving them be is hurting businesses and ruining reputations.

    No. No they’re not.

    What ruins your reputation is how you reply to them. If you accuse them of being spammers or harassers, you make yourself look bad. If you lay into them because you disagree with their review, you make a fool of yourself. A review is a ‘how I feel’ from a user, and even though you may not agree with their conclusions, that doesn’t make their experience invalid. It means there was a breakdown in communication somewhere between you and them.

    This is why I tell people to check their documentation. If they’re getting a lot of bad reviews that are plain wrong, and they’re wasting a lot of time talking to people and correcting them, then the issue has to be, in part, the information they’ve presented up front. If its not there, add it. If it’s there, point them to it. “Actually I answered this in the FAQ where it says this plugin is Multisite only.” True story, I have to use that a lot.

    But when that question comes up time and again, I may ask “The FAQ covers this here LINK. Do you think there’s a better place I can put that? Where were you looking so I can make it more obvious for the next guy?”

    Maybe they never reply and fix that one-star review, but when people go and look at the reviews and see a one-star, and read it, they’ll see my mature, reasonable, honest reply. And that will do far more for my reputation than anything else.

  • Uniqueness Matters

    Uniqueness Matters

    This email gets sent a lot to plugin devs lately:

    All plugins should have unique function names, defines, and classnames. This will prevent your plugin from conflicting with other plugins or themes.

    For example, if your plugin is called “Easy Custom Post Types”, then you might prefix your functions with ecpt_{your function name here}. Similarly a define of LICENSE would be better done as ECPT_LICENSE.

    Please update your plugin to use more unique names.

    And once in a while someone asks why we care so much.

    There are 38,308 active plugins in the WordPress.org repository. If every one of them uses a global define of IS_PLUGIN_SETUP then they will all conflict with each other. If half use a script handle of plugincss then all those plugins will stomp over each other when it comes to enqueuing the CSS.

    It’s literally a numbers game.

    Every day we get at least 30 new plugin submissions to WordPress.org. That means every day at least 30 new potential conflicts show up. And it’s not just plugins. In WordPress 4.2, a new function was added: get_avatar_url()

    This was a great idea that saved people countless hours of work. Unless they logged in to see the error Fatal error: Cannot redeclare get_avatar_url() prance across their screen.

    Now in this case, theme authors had previously been told to include/make themselves, but was later added to core. All theme devs hosting on WordPress.org were notified and it was posted on the change blogs. But not everyone remembers to check those. And not everyone updates their themes right away. In a way, this probably could have been communicated better, but had the themes called their function mythemename_get_avatar_url() then this wouldn’t have been a problem.

    Prefix everything. Make it unique to your plugin or theme. WordPress is ‘home free’ and shouldn’t have to, but you should.

  • Trust the Changelog

    Trust the Changelog

    Recently there were a couple WordPress plugins with fairly major security fixes. But you wouldn’t know it by looking at their changelogs.

    The changelog is a section of a product’s readme that describes what changed. For most people, it’s a list of items like this:

    • Added feature X
    • Corrected typo
    • Security fix

    The problem many people have is that last one is often left rather vague. I’m guilty of this myself. In a recent fix, I simply said “Security fix: Sanitizing _POST calls to prevent evil.” and “Security Fix: Implementing nonces.”

    The primary reason we keep change logs a bit vague is because we don’t want to open the door to alert hackers as to vulnerabilities. People don’t update their code right away, so every time we publicize a security issue, the people who haven’t updated immediately are at greater risk of being hurt.

    But if we don’t tell people how important it is to update, how do they know how important it is to update?

    There’s the real issue. There’s not yet a proper balance between “You should upgrade as soon as possible” and “You need to upgrade now, or you’re doomed.” My security issue was only accessible by people with admin access. It would be possible to trick an admin, with a cleverly crafted page, but … The effort it took me to apply a nonce check and sanitize things is minimal. From my end, it’s very minor of a fix. From a user’s end, it’s an exceptionally rare hack and unlikely to occur.

    The right answer here is “Always upgrade to the latest version of code as soon as possible.” The problem is “as soon as you can” gets bumped out if it’s not mission critical. A patch that adds in a filter? Not a big deal. A patch that secures my site? Should be a big deal. I would argue that any time anyone says “This is a security fix” then you shouldn’t have to concern yourself about how likely the hack is to impact. Instead, security is a watchword to tell you to update the software “immediately.”

    Which brings us to two agreements we need to start making with people. The agreement of developers to do things ‘easier’ for users and the agreement of the users to trust developers. If we want people to upgrade, they have to trust us. And if they’re going to trust us, we have to be reliable and consistent.

    As developers, we promise not to flag something as a critical security fix that isn’t just security fix. If there’s a major issue with our code, we will push a patch as soon as possible that only deals with that issue. There will be no feature changes, no little fixes, no minor tweaks. A security release will only be a security release.

    Furthermore, to enable people to update properly, we will properly use semantic versioning. This will allow us to update minor releases as far back as logical, because you can know that version 1.2.8 is the latest version of the (old) 1.2 branch, and 1.5.3 is the latest of the (current) 1.5 branch. The next time we add in new features, we will properly version our code as 1.6 so that you know what branch is current.

    As users, we promise to trust your security-only releases and upgrade our copies of your code when a minor release that is a security issue is released. If you release a version 1.5.4 and not a version 1.4.4, we will trust that either the 1.4 branch is not subject to this security issue, or the fix could not be back-ported. If you inform us that we must upgrade to the 1.5 branch because there’s no way to secure 1.4, we will expedite our upgrade.

    In order to enable ease of upgrade, we will not edit our code to make it impossible to change. We will properly use functions and actions and filters and hooks. We will make regular backups as well as immediate ones before upgrading.

    Of course… That’s a perfect world. But I’m going to do my part as a developer and start versioning better. If I do that, and if I as a user hold up my other end, then we can get to a place where all disclosures of security issues happen in tandem with a release, as we know that everyone will upgrade immediately.

    A place of trust.

  • Heartbeat API

    Heartbeat API

    For the longest time I didn’t really get the heartbeat API. I get the very basics of it, but it took me a while to understand what it was really doing.

    We’re used to interacting with our websites in a very one-directional way. I click a link, I go to a page. Heartbeat API is a bi-directional communication, which can best be translated as ‘shit happens without you having to click.’ The browser and the server are happily chatting to each other all the time, without me having to do anything.

    If you’ve ever used Google Docs or MS Word or Apple Pages and noticed you don’t have to press ‘save’ all the time, that’s the idea of a Heartbeat API. It does the background things for you. That thing you should do (save often). In WordPress, the most obvious thing that Heartbeat does is it saves your posts as revisions.

    That doesn’t stop neurotics like me from pressing ‘save’ all the time.

    Of course, this can get a little expensive, checking all the time, so the Heartbeat API is smart. It only checks every 15 seconds by default (you can change this), and it only checks when you’re on a page doing something. If you just leave a page open, it slows down and, after an hour, turns off.

    But besides saving, the Heartbeat API can share information between the systems. For example, it can ping out to Jetpack and check if it’s up and everything’s working, or if you have to reconnect your LinkedIn settings. And since it’s javascript based, it doesn’t reload the page.

    You can use it to alert logged in users to new content. Imagine a post that suddenly had an overlay of ‘This post has been updated…’ Doing that requires two parts:

    1. Hook into the send call and add your data
    2. Hook into the receive call and show the data

    Pippin has a great heartbeat API example but he also warns people:

    I’ve managed to bring down server servers by using the Heartbeat API on the frontend.

    If you trigger things to be called too often, you can totally crash a server.

    The Heartbeat API is a step towards making our sites really responsive and modular. Instead of statically checking via PHP if someone’s logged in and changing display based on that, Heartbeat can dynamically change on the fly. This would allow caching systems like Varnish or static-file caches like WP Super Cache, to save the cache and speed up your site while still being dynamic. It lessens the weight on wp_ajax_ and makes things work with caches, rather than bypass them.

    And that will make our sites beat faster for everyone.