Long Form Posts
- Clicking “Let me read it first” works: it slides away and the most recent posts show up. Guess it’s just a simple HTML overlay blocking the home page.
- Open all links in a new tab. Just clicking them will run some JavaScript which, I guess, tries to load the post directly from Substack, resulting in an error if the newsletter is taken offline. Opening the link in a new tab will get the post directly from the Wayback Machine.
- Clicking the archive tab seems to bring up the blog archive briefly, but then some JavaScript — which I guess is trying to load the archive from Substack? — replaces it with an error (why does everything need to be JavaScript?!) I’m guessing that the actual HTML is still there so it might be possible to get it if you disable JavaScript. I haven’t tried this though, so this is only a hypothesis.
- My hands must not move from where they rest on the keyboard for almost the entire time a file is being worked upon. The only exception are actions that are invoked less frequently and have a large radius of change — such as the accepting all changes from the left or the right. I’d figured it’s still okay to use the mouse for those.
- The arrow keys should be used for navigation (go here) and for addressing (this one).
- The modifier keys should be used for choosing the operation, such as going to the next delta, or choosing or ignoring a change.
-
It was previously something else, and I have no idea how it got changed. ↩︎
- AttributeValue API documentation: this the definitive guide from AWS.
- DynamoDB Item size and format: more info about the particulars of each attribute type.
-
It gives the impression of hustling me. I appreicate the time you take to publish something that I see value in, but sending these reminders feels like your forcing your content onto me. Like I just got to read this content. Really, you must read it! And, oh! You forgot this one day? Well I’ll make sure you don’t forget it (and me) again. Please, back off! I’ve received your content and I’ll get to it when I get to it, if I feel like it, after I’ve read all the other newsletters I received. Please don’t push me to read it on your schedule.
-
It just confirms that they’re tracking what I open. I mean, I know this aready, but it does bring it front of mind.
- Continuous integration — not the automated build kind, but the consistently merging into main kind — is not only important, it’s bloody vital. Not doing this means that you’re left with little confidence in what the testing team is actually testing is what would be pushed out to production. Using the epic feature branch was a mistake. Always merge to main, and test from main as often as you can. You may need to push out changes that are turned off, but as long as you design for this, this should be fine (feature flags FTW).
- Letting tickets pile up like they did was another mistake. Ticket flow is important: not only for the team, who’s morale is tied to whether we will pass the sprint or not, but also in finding any problems early enough that you have enough time to react to them.
- This is probably something on my head: don’t spend too long doing a design. I spent a week on one when one probably could have been written up in a few days (to be fair: the scope of the work has not quite been locked down when I was doing the design work, which did delay things a little). A quick design also means getting feedback sooner.
- I think the largest takeaway is trying to check the businesses expectations on what can be delivered and when. This I find the hardest thing to do. I’m a bit of a “aim to please” type of person, so it’s not easy for me to say something like “we can’t do that in that time.” Instead I tend to be quite optimistic about what we can deliver. I have to get better with this.
The Australian Republic Question
With the passing of Queen Elisabeth II, the talk of whether Australia should become a republic will probably start making the rounds once more. I don’t consider myself a royalist, and when the last referendum on the issue came around, I voted in favour of becoming a republic. The idea of having the British Royal Family as the head of state of a country halfway around the world seem anachronistic to me, and I was disappointed when the referendum failed.
Since then, my position has been become slightly more nuanced. I still believe in the ideals of becoming a republic — in being a country that is more-or-less completely self governing. But after reading this article from Vox.com, I’ve come to see some benefits of having a head of state that is removed from the day-to-day politics of government. Sure, the stability from such a figurehead may not have been wholly constant, but that “lack [of] semblance of legitimacy” that comes from the royals being the head of state does provide some reassurance. One less divisive thing for people to think about when that position changes hands.
So if the referendum was held today, which way would I go? I’d probably still vote “yes”, but it would have a “can we make it such that the office is not in any way marred in the politics of the day?” qualifier attached to it.
Then again, I talking about the terms of a theoretical referendum where the proposed system is more than just replace-the-monarchy-with-a-president. Such concerns regarding the division of power might already be settled within the constitution. I really don’t know: might be worth looking up if the question were to come up again.
Either way, we’ll see which way the winds blow.
Detecting When GetItem On DynamoDB Returns Nothing
I was trying to remember how best to detect when a GetItem call to DynamoDB returns no values. That is, when there’s no item with that key in the table. This is in a project that is using v2 of the Go AWS SDK.
After poking through some old code that did this, it looks like the way to do so is to check that the returned Item
field is nil
:
out, err := p.client.GetItem(ctx, &dynamodb.GetItemInput{
Key: key,
TableName: tableName,
})
if err != nil {
// Error getting the item
return nil, err
} else if out.Item == nil {
// No item found
return nil, nil
}
// Do the thing with out.Item
Ok, I can live with this approach. I’m kinda happy that I don’t need to check the error message, since doing so using the Go AWS SDK is a bit of a pain.
Milestone
For a while, I’ve been trying to maintain a writing streak. I need to write at least one blog post or journal entry a day. Today that streak has been maintained for a full year.
I will admit that the streak was not completely continuous: I had to go back a few times and retroactively add a post. But even so, I’m quite please with reaching this milestone. Onward to the next one.
Some Things I Found Out While Browsing a Substack Newsletter in The Wayback Machine
I did a quick search for that blog post in the the Wayback Machine. I couldn’t find the post but the Substack newsletter was there. I guess Substack does allows archiving of newsletters with the “substack.com” domain after all (if it’s something that they can even control).
Anyway, here are a few things I’ve found out while browsing through a Substack newsletter in the Wayback Machine:
As for the post itself, it turns out that it was in my Feedbin archive all along, so the search in Wayback Machine wasn’t actually necessary. Now the trick is to find a way to prevent Feedbin from purging old posts. 😳
Rebinding Keys For Quickly Resolving Conflicts in GoLand
I’m dealing with a lot of conflicts today as I try to clear a backlog of Git rebases in my to-do pile. I’ve been using GoLand to do this, as my current Git “mergetool” is configured to Vimdiff for some reason1 and I’m not really bothered to find some other tool, at least not yet. GoLand does a pretty good job.
Unfortunately, the default key-bindings for resolving conflicts in GoLand is far from good. About the quarter of actions are bound to keys that make sense. Half the actions, like ignoring hunks, are not bound to anything, while the last quarter are bound to keys that result in a suboptimal experience. For example, the key to accept changes for a delta use the arrow keys, whereas the key to go to the next delta is F7. What a strange default. I’d have to constantly move my hand off the arrow keys over to the Fn row if I want to go through and fix each delta. This, plus moving over to the mouse to select an action not bound to a key, makes resolving conflicts really slow.
Fortunately GoLand allows remapping keys to pretty much anything, so I’d figured it’s time to fix this problem. I set about coming up with a nicer key-mapping scheme for resolving conflicts. I wanted to come up with one that adhered to these principals as best it can:
Here’s the key-map I’ve come up with. The actions marked with an asterisk were the one’s that I needed to change. All these actions are within the “Version Control Systems > Diff & Merge” group within the “Keymap” section in preferences.
Action | Key Binding |
---|---|
Previous Difference * | ^⌘↑ |
Next Difference * | ^⌘↓ |
Previous Conflict * | ^⌥⌘↓ |
Next Conflict * | ^⌥⌘↓ |
Accept Left Side | ^⌘→ |
Accept Right Side | ^⌘← |
Ignore Left Side * | ⇧⌘← |
Ignore Right Side * | ⇧⌘→ |
Confirm Merge | ⌘Enter |
I’ve only tried this out as part of a single rebasing session, but already it feels so much faster. It’s taken me probably half the time to go through each file now, maybe even better. I also like the fact that most of the time I only need to hold down Ctrl and Cmd key, and use the arrows to move to and accept changes. Ignoring a change involves moving my left pinky to the Shift key, adding a bit of resistance to indicate an action that requires just that little bit more care.
We’ll see how this goes as I deal with future conflicts, and I may make a change or to. But this is looking really promising.
One last note: this was done in GoLand but I’d imagine it’s possible to set this key-mapping up in most, if not all, of JetBrain’s other IDEs.
Turning Off Shared Command History in Oh My Zsh
TL,DR: add “unsetopt share_history” to your .zshrc file
I’ve been using Oh My Zsh at work for a few months. As far as terminal config managers go, this one works pretty well. But the default configuration does include something which I found quite annoying.
First, a few words on how I use the terminal. I’m in the terminal constantly in my day to day. At the start of the day, I’m creating terminal tabs and running commands to do things like build the project I’m working on, start a testing session, etc. This all starts very ad-hoc, but over time these tabs take on a particular role. I may run make
and git
in the left-most tab, run tests in the tab next to that, have logs tailing in the one after that, etc. As I start and stop commands in each tab, they all build up a different history, which is usually visible in the terminal output itself. Eventually it comes to the point where in order to run a particular tool, I simply need to switch to the particular tab and press ↑ one or two times to get to it.
Installing Oh My Zsh broke this workflow. Out of the box Oh My Zsh enables shared command history across each session, meaning that the commands recalled when pressing ↑ are the last commands executed in any tab. This meant that when going through the history, the recalled command would be different from the ones that I’ve entered in the tab I’m in. In addition to this resulting in pressing ↑ way more times than I used to — sometimes to the point where I gave up and simply typed the command out again — it also meant that the recalled commands differ from the ones I saw in the tab output itself. This was very jarring.
Fortunately, this feature can be turned off simply by adding the following to your .zshrc file.
unsetopt share_history
I did just this and my old workflow was restored.
I don’t know why shared command history was chosen as the default. Am I in the minority using the terminal this way? Maybe. But I know for certain that this group is larger than a single person. In either case, I’m glad that I was able to disable this “feature”.
Kyneton Botanical Gardens
Went to Kyneton with Mum and Dad today. While they went off for a bike ride, I had the opportunity to go for a walk around the botanical gardens. This was my first time there, and although the gardens themselves were not very big, it was still a pleasant experience. Here are some photos I took of that visit.
This was followed by lunch at Little Swallow Cafe. The place was quite busy — I suspect that their reputation is such that it would be busy most of the time — but the food was very nice. We then went for a short walk around Kyneton and then drove to Malmsbury for a coffee and Devonshire tea.
It was a little cold but the rain held off. All in all, a good day for it.
DynamoDB JSON Attribute Types Quick Reference
Because apparently it’s too difficult for AWS to provide an easy way to find this information.
Atomic Types
Type | JSON | Value |
---|---|---|
Binary | B |
String value containing the Base64-encoded binary data. |
Boolean | BOOL |
Either true or false |
String | S |
String value |
Number | N |
String with the numerical value |
Null | NULL |
Should always be true |
Collection Types
Type | JSON | Value |
---|---|---|
List | L |
A JSON array, with each element being an attribute with a type. |
Map | M |
A JSON object, with the keys being the map keys, and the values being an attribute with a type. |
Set Types
Type | JSON | Value |
---|---|---|
Binary Set | BS |
A JSON array of Base-64-encoded binary data. |
Number Set | NS |
A JSON array of string with the numerical values. |
String Set | SS |
A JSON array of strings. |
Sources:
More Complaining About Autocorrect on MacOS
Earlier this morning:
Me: (writing in my journal) Nonna, my 91 year-old grandmother…
Autocorrect: Did you me “Donna”?
Me: No, undo change. (continue writing) good news is that Nonna…
Autocorrect: Did you me “Gonna”?
I can forgive MacOS for considering nonna a spelling error, since it’s not an English word.
But I do see why auto-correct on MacOS can be frustrating. Apart from the two completely random corrections it made for the same word, it also doesn’t seem to get the hint when I undo the change. I would have thought that action is a pretty strong signal from the user to just leave the word alone, at least for the moment.
Write It Down
I am feeling some very minor after-effects from the booster I took yesterday (nothing serious, just the expected cold-like symptoms). I was curious as to whether it was anything like I experienced in January, when I got my last booster. I went to my journal to see what I wrote about it. Unfortunately for me, there was nothing there.
To be fair to my past self, there were some other events going on at the same time which I did write about. But I was left pondering this morning about why I didn’t write anything about how I was feeling back then. My guess is that I probably didn’t think it was worth writing about at the time. “Feeling a little off” was probably something that I thought was quite trivial, and wouldn’t be relevant later on.
I was wrong: it was relevant. Otherwise I wouldn’t be going back in time to find out.
I guess there’s a lesson there: write it down. Write everything down, even if you think it might not be relevant at the time. The simple fact is you don’t know. It may very well be relevant months or years from now. Better to written down too much than not have anything written at all.
Of course the trick is working out what “everything” consists of. If you’re writing down what constitutes your daily routine each day, I’d imagine you’ll be spending most of your time documenting the same thing over and over again. I guess a good decision process is if you’re unsure about particular thing, then it’s probably a good idea to just write it down anyway. You may think it’s unnecessary at the time, but again, you don’t really know.
I’ll try to get better at this myself. In fact, part of this post was taken from this morning’s journal entry, just below a description on how I was feeling today.
Newsletter Reminder Emails
I subscribe to a newsletter that sends “reminder” emails if I skip an issue. If I don’t open one of the email newsletters I receive, then a few days later, a copy will be sent with a forward of the form “looks like you skipped an issue. Here what you missed.”
These reminder emails are bad, and here’s why:
If you’ve got an email newsletter, please don’t do this. It could just be me, but I don’t read every issue of every newsletter I receive, apart from a few exceptions. If I’ve subscribed to yours, then know that I get value from your content. Really, I do; I wouldn’t have subscribed otherwise. But sending these reminder emails out do not do your content any favours.
The Feature Epic (Featuring the Epic Feature Branch)
Here’s what’s been happening at work with me recently. I write it here as an exercise in how I can learn from this. They say that writing can help in this respect so I’m going to put that logic to the test (in either case, just having this documented somewhere could prove useful).
We’re working on a pretty large change to the billing service powering the SaaS product sold by the company I work at. Along with our team, there are two other teams working on the same service at the same time, making any changes they need to release the product stuff they’re working on. All our teams had our own deadlines — which are pretty pressing — to get stuff delivered either last month or sometime this month.
Knowing that this was a change that could impact these other teams, I came up with the idea of using an epic feature branch, which will be used to track our changes. This will leave the main branch relatively free for the other teams, who’s changes would not be as invasive as ours, to proceed with their plans and release when they need to without us blocking them. Great idea — everyone can work at their pace.
Of course, if it was such a great idea, this blog post would be a lot shorter. 😉
This started out well. We were doing our thing, making our changes and committing them to this epic branch, occasionally pulling updates from main when we started to fall behind. The other teams were merging their changes on main, and the CI/CD pipeline was dutifully deploying what they merged into the dev environment.
Then, after a couple of weeks, things started to go a little wrong. The changes from the devs started to pile up in the “Ready for QA” column of our Jira board. The team was a little concerned that the changes we were making couldn’t be ready for testing until they were all finished and merged. Given the way the tickets were written, this seemed like a fair enough argument (I was the one that wrote the tickets BTW), but this delayed testing of the changes to the point when we we only had a few days to complete our testing and push it out to production before we hit our deadline.
Once the QA team was ready to proceed, disaster. Many of our changes had bugs or issues that we didn’t foresee, and had to be fixed or new tickets had to be spun out. We had to delay rollout by more than a week (at the time of this post), which made the business quite unhappy. Making things worse was the use of the epic feature branch and the automated deployment of main to Dev. The other teams were still doing their thing on main, and when they merge a change, it blew away our changes. This resulted in the QA team coming to the dev team with issues which, after investigation, were largely because the our changes were not even there.
One other thing I didn’t forsee was that when we get to the point of merging our epic feature branch into main, I had little confidence that it would be integrated correctly. The sole reason for this is that the test team hasn’t been testing our changes from main. They’ve been testing the epic branch just fine, but all those conflicts that were resolved during resyncs from main, plus the actual large-scale merge of our branch: what’s to say that we didn’t miss something? We’re just right back to delaying our testing near the due date.
So this is where we are now. All the bugs (that we know of) have been addressed and I’m hoping to merge our changes into main today in preparation for what I hope to be one last test before we roll it out.
So, what did I learn from this? I can think of a few takeaways:
The saga is not quite finished yet: you may see another blog post on this subject soon enough. But hopefully things will settle down after this.
Arriving Late
I’m going to have to tell my boss today that the stuff my squad has been working on is going to arrive late. To much needs to be fixed or reworked, and there is one or two things that have been missed alltogeather.
I think the biggest problem is that the thing we’ve been working on got into testing far too late — only a few days before the deadline — meaning that there was no time left for fixing things. Really, you can draft all the plans and designs you want but you really don’t know how well it will perform until the “working” code has been handed to someone else.
Another problem might have been that I didn’t push for more time upfront. It’s been difficult to do this in the place I’m working now. It’s almost like they’re on to me (or at least have their own ideas of when things should be delivered). But I’m guessing it’s still heaps better to shatter expectations by saying something will take longer upfront, then get it delivered early, rather than be optimistic about it and come up against the deadline. “Underpromise and overdeliver,” they say.
I wonder if there’s a way to have two deadlines: one the business knows about, and one for the squad. The first one is quoted to be a respectable amount of time that is significantly larger than what you really it would take to deliver the feature. That would check expectations, and leave enough time for any rework. The second is a more optimistic deadline for the squad to work towards. I think having this second deadline is important, otherwise all the work will pile up near the end of the first one and you’ll deliver late again. It’s all so deceptive though, and the thing is that you almost need to deceive yourself: you know that the second deadline is not the “real” deadline after-all.
I don’t know. I find all this estimation and managing expectations quite difficult and it’s generally not something I like doing.
In any case, we’re going to need more time. I guess I can take solice in the fact that we almost got there, maybe 70-80%. We just need to get that other 80% over the line.
Wrong Number
Got called three times this morning by mistake from an old woman in NSW trying to contact her son who had a very similar phone number to mine.
First time I ignored it as I didn’t recognised the number and thought it was spam.
Second time I answered and after trying to understand what she was trying to say, I simply said “I think you got the wrong number, sorry” and hung up.
Third time I answered and after recognising that it was the same person, I figured it was right to work through the problem with her. So I spend some time with her, going through each number slowly, trying to make sure that we understood where the mistake was made. I didn’t hang up until I got the sense that she understood what number she needed to dial. I was trying to be helpful, but I’d be lying if I said that self-interest was not involved. After all, I wasn’t too keen on getting any more wrong numbers.
Four hours have passed and I yet to hear from her again.
Is there a lesson involved? I don’t know: this could have happened to anyone. I guess if there is one, it’s that sometimes you don’t get to choose the types of problems you need to work on, and you just got to do what you can to, if not solve them, help in making them less of a problem than they were before.
Honour, Democracy, and Galati: A Day in Canberra
Since being in Canberra, I haven’t really done anything “touristy”. Given that today was a public holiday, I figured it was as good a time as ever to do so. So I decided to spend the day visiting a couple of national landmarks, plus something I’ve been planning to do since returning to Canberra.
The War Memorial
The first time I’ve ever been in Canberra was during Christmas holidays in 2007 my family. During that time, Mum and Dad and my two sisters went to the War Memorial and Parliament House, while I stayed in our rented town-house. The reason why I stayed back was a little embarrassing: I claimed that I was tired, but this was during a weird period where I didn’t really want to be seen doing something touristy (I’ve mostly got over this feeling). Not going when I had the chance was something I’ve regretted since that day. Well, today I make amends with at least one of these, with a visit to the War Memorial.
Old Parliament House
Following my visit to the War Memorial and a brief lunch at the Poppy Cafe, it was time to visit Old Parliament House, and the Museum of Australian Democracy.
Following this was a brief walk around the gardens.
The City, And Galati
My final stop was the city. Why? Well, during my visit in April, we found a really nice galati place where we stayed, and since knowing that I would be back in June, I made it a point, in half jest, to return. When talking to Mum and Dad on the phone, they asked if I have fulfilled this promise. So since I was nearby, it felt like the perfect time to do so.
Despite how sunny it was, it was still quite cold. But even so, that galati hit the spot.
My Evening
So here’s how I spent my evening:
Watching the WWDC state of the union until the DNS resolver konked out in the WiFi router, causing the Chromecast to get into a state in which it could no longer connect to the network, resulting in about 10 minutes of troubleshooting before deceiding to clean up, not go to the gym, spend another 10 minutes trying to troubleshoot the issue, then stared at my laptop for about half an hour wondering whether to go back to troubleshooting the Chromecast, or doing something else with the hope that it would eventually work itself out.
Eventually, after another 5 minutes of fruitless troubleshooting, I finally got the Chromecast fixed by doing a factory reset and connected it to the 2.4 GHz band.
Anyway, I hope your evening was more productive than mine.
(And I was worried I would have nothing to write about today.)
The Powerline Track Walk
Went on a walk of the Powerline Track, which I was personally calling the “powerline walk” (yes, I’m impressed at how close I was). I saw this trail when I was in Canberra earlier this year, and knowing that I would be back, I made a note to actually walk it, which I did today. This track follows the powerlines just south of Aranda Bushland Nature Reserve, then goes under Gungahlin Drive and into the Black Mountain Nature Reserve. The weather was cold but pleasant, at least at the start of the track. It eventually got quite dark and a little wet near the end, but that did result in some nice winter lighting over the landscape.
Here’s a gallery of some of the photos I took. Note that there’s a fair few of powerlines, which is something I’ve been drawn to ever since I was a little kid.
Humour In Conference Videos — Less Is More
It might be just me but I get a little put off with over-the-top attempts at humour in developer conference videos.
I’m four minutes into a conference video which has already included some slap-stick humour (with cheesy CGI), and someone trying to pitch to me on why what they’re talking about is worth listening to. This was done in such a way that it actually distracted me from the content, a.k.a. the reason why I’m watching it.
This sort of thing is really a turn-off, almost to the point where I feel like turning it off. I also don’t think it helps you that much either. If you open your talk by pretending to get zapped by a piece of lab equiptment, I’m probably not going to assume the same level of sincerity in your presentation as I would for someone who is just trying to get their message across.
I like a joke as much as the next person, and one or two small, well contained jokes like substituted words in the slide pack is fine. But it really needs to be dished out in small doses, and it really shouldn’t distract from the content. Less (and much less than you think) is more in my opinion.