More Disconnection Thinking

Here on the ship, we have satellite Internet. This means that, at a good moment, I’ve got round-trip ping times to at just over half a second (~660ms) and download speeds that seem to average around a megabyte per minute. Furthermore, access to the satellite Internet is on a paid basis, so you have to authenticate with the ship’s portal before you can get to the rest of the world. Oh, and the portal requires you to re-authenticate after two hours.

Now, when we’re ashore, we can get data on our phones. We have a swell (expensive, but swell) international roaming plan, which means that when we get into port we get this swell text:

Welcome to Indonesia. You have TravelPass, which lets you use your domestic plan for $10 a day. Pay only on the days you use your mobile service. Use talk, text, or data to start your session. You’ll get 2GB of high speed data. Then enjoy unlimited 3G data for the remainder of the session.

Which is great-ish, when the cell network isn’t overloaded by, say, a couple thousand other people trying to download stuff.

Meanwhile, my phone operating system is a couple of point releases down-rev from the latest. At least one of these releases is a security update, and I’d really like to get that applied since I’m far from my home network. Oh, and how big is that software update I want to download? And it’s competing with what other baloney the apps on my phone are trying to download at the same time? There’s the “solve this particular problem” approach, which is to force my phone to download the update as soon as we hit port, and leave it plugged into a backup battery so that it thinks it’s docked and doesn’t abort the process. But that’s really ignoring the fundamental problem: sometimes, you really do need to receive a large file sent over a slow and/or unreliable link.

Back in the days of dial-up, this was handled by the transport layer and we were all a lot closer to that transport layer. An xmodem file transfer would fail at 98% of the way through if there was suddenly a bunch of line noise (like your roommate picking up the extension) and you’d have to start all over again. So, we used zmodem and were able to resume a download. You can still see this kind of feature in a browser, when you’re downloading some godawful huge file and then, in the middle of the download, you unplug your network. You can often resume the download.

This “resume download” feature isn’t part of the operating system, though (or, not for Linux, iOS, Android, Windows, or MacOS, anyway) but rather a feature of the program initiating the download — in the above example, the web browser. So, what if the thing that’s trying to do this massive download (or upload) isn’t a web browser, but a standalone application? Unless the developers of both the application you’re interacting with and the remote application it’s talking to have already thought about this problem, then the answer is probably, “You’re stuck.”

Now, it’s easy to start decrying the popular frameworks (Electron, Flutter, et al.) that hide even the possibility of handling this well deep inside some barely, if at all, accessible network library, but that’s neither productive nor even fair. It’s still a hell of a lot of work even when you have access to the file system and the low-level networking calls to send/receive a small buffer of bytes. The real situation is, most developers don’t even consider what this somewhat-connected experience is like.

When HTTP was the protocol for data transfer, you could run a caching proxy and then do silly tricks like fire off requests through the proxy for the big things and then unplug your computer. Weaknesses of this hack aside, that’s not how we do things anymore. Nowadays, we assume that there are bad guys warping all the data we send and receive, so we encrypt everything. That means that sticking a proxy in the middle just won’t work — to the apps on both ends, the proxy looks the same as a Bad Guy.

So. Developers. When you’re coming up with a server API that allows for transfer of large blobs of data, please consider a RESUME endpoint.

And, developers, when you’re writing some client for an API that provides a RESUME endpoint, make use of it.

Hobby Utility

So, we’re on a cruise ship and I got to thinking about the population and the environment and I developed a morbid curiosity. More about that below the fold. The high point, though, is that I’ve written another application — this one for the iPhone — that fills a neat, narrow niche: it’s a combination tally counter / lap timer. I call it MTBP, for Mean Time Between Phlegm, and that right there is a big clue about the rest of the post.

Continue reading “Hobby Utility”

Satellite of Something

It’s day two of our Atlantic crossing and I’m getting the feel of the ship. It’s a really good thing I did all that setup work to enable offline coding, because the Internet is available mostly in a philosophical/mathematical sense. For example:

% ping -c 5                                                                  ✹
PING ( 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
64 bytes from icmp_seq=3 ttl=55 time=797.729 ms
64 bytes from icmp_seq=4 ttl=55 time=728.960 ms
--- ping statistics —
5 packets transmitted, 2 packets received, 60.0% packet loss
round-trip min/avg/max/stddev = 728.960/763.345/797.729/34.385 ms

Continue reading “Satellite of Something”

Here’s a (docker) image for you

We’re getting closer to a long vacation with intermittent Internet, so I’m going through all my developer tools, making sure that everything’s ready. Now that I know how to get VSCode to persist its downloaded stuff between runs in a given container (make sure there’s a .vscode-server/extensions directory in the container user’s $HOME), I wanted to see if I could get SwiftLint working as well.

Continue reading “Here’s a (docker) image for you”

Oh, Xcode

Okay, so, Mastodon. Yay, there’s a web interface! Great, but…do you know anyone who wants to interact with, say, Twitter, via the web interface and not some app that makes it easier to deal with? Right.

Enter Mastonaut, except it got started before SwiftUI was really a thing for macOS, so it’s all AppKit and storyboards and NSManageMemoryBecauseThatsWhatRealProgrammingIsAbout.

And at some point yesterday I saw some yahoo claiming that because he’d never made a complex application with SwiftUI then it couldn’t be done.

And then there’s MastodonKit, which purports to be a library that wraps the Mastodon API, but which is missing stuff and which doesn’t seem to merge pull requests. But that’s okay because you can just fork it and do your own thing, never mind the overhead of tracking any API changes or bug fixes that other people might find.

And what’s really cool is how really well Xcode doesn’t deal with git submodules and Cocoapods and swift packages. Especially when someone changes one of those things and checks it in and then you pull that change.

Mysteriously and for no reason, I can no longer build this app. So…okay, roll my own. Because that’s what open source is all about, isn’t it? Being unable to reproduce someone else’s code so you just ignore it all?

I’m Dead, We Have So Many Forks

The post title is something one of our kids said, years ago, when our utensils drawer contained the combined tableware of two adult households. They were spoiled for choice.

Anyway, since suddenly people I actually want to stay in touch with have started showing up on Mastodon and following me, I have started paying attention to the client app I use to interact with it. The original creator released it as open source and walked away, but it’s been picked up by a few people. So, I started feeding code updates back to the community. But, and here’s the first thing, which copy of the source code is the one that I should be feeding changes to?

Continue reading “I’m Dead, We Have So Many Forks”


I am gonna surprise precisely no-one by saying, I do not like conflict. I’m conflict-avoidant. I don’t like having to confront someone and tell them they’re wrong, or that I don’t like what they’re doing, or anything even close to that. That means, of course, that when I’ve finally got the determination to enter conflict, I do so with disproportionate force. Because I’ve got to overcome all my internal reservations, at the point I manage to tell someone that I don’t like what’s going on, it can seem…over the top.

So yeah, today. The specified fireplace for the ADU will look amazing, but will provide no heat. So, is fire pretty enough that we’re willing to spend over 20 grand just to look at it, without any other benefits? Not in my book. So, I take a trip over to the fireplace showroom after calling and getting routed to voicemails for both the business and for the specific salesdude on the proposal. Rando employee tells me that no, that model of fireplace is really just for looks — it doesn’t heat anything, appreciably. He shows me some other models that will, actually, heat a room.

And now, the conflict. I send an email to the architect & builder saying that no, they’re gonna have to suck it up and get a different fireplace. Builder says, “Sure, just let me know what the framing requirements are going to be when you figure out what you’re actually going to buy.” That’s real. That’s a guy who has no investment in the choice beyond being sure he can do the job.

The architect? He comes back at me with reasons why I should just take the stupid useless climate destroyer. You know what? The more we go along, the less happy I am about this choice. Why do I need to argue about my desire to have a fireplace that actually provides heat? Why is this even a discussion?

How Do You Talk to the World?

There’s nothing like a natural disaster to get a person thinking about resilience. In 2020, lightning struck and started a fire in some dry brush in a canyon near Davenport, and the fire spread and took out nearly a thousand houses. While the fire was spreading, PG&E, which owns and operates the power distribution network in the mountains, even though generation is provided by someone else, kept cutting the electricity off. Probably to keep the wires from dropping and starting more fires, but who knows? Anyway, the lack of electricity meant that water pressure pumps, wells, and thus in-home sprinkler systems were just so much metallic debris to be cleared along with the ashes of houses. As we rebuild, connecting to the electric grid that works unless you need it to is not part of our plan.

And then, there’s Internet and phone service. Cellular coverage in the mountains is spotty, and not really extant at our property. Getting decent speed up there is a challenge, as well. Currently, the only real option is Comcast, and that comes bundled with a few problems. It costs a lot, it’s only as reliable as the PG&E grid, it’s got pathetic upload bandwidth, and the shitty wiring means that service gets degraded whenever someone in the neighborhood turns on their A/C (that was the one downside to living near a grow house).

But that’s really the only game around. I mean, sure, we could go with Dish, but that’s got even worse upstream. And we’re too far from anything for DSL, even if the thought of a Zoom call over DSL didn’t give me headaches. And then, Ars Technica ran a story about a local-ish company the helps build out community owned fiber networks. This would in no-way be cheaper than Comcast, but it would absolutely have better customer service (I mean, it would be really very challenging to have worse) and the speeds would be amazing. I reached out to Next Level Networks to find out if there were already a group in/near Bonny Doon that I could hook up with. They said no, but if I could drum up enough support among my neighbors then they’d be happy to work with us.

I am not a good organizer. If I were, I’d still be on the board of my pipe band. However, I mentioned this to my wife and she said that a community co-op ISP would be fantastic and she’s all in favor. So maybe in Q2 of ’23 I’ll go start having conversations with neighbors. I think everyone will be happy to have multiple options available, because there’s nothing like an emergency to demonstrate just how much monopolies suck.

Language Feelings Matter

I just finished a first pass at implementing a new feature in an application I wrote in Flutter. I’ve been working hard at it, not letting myself get distracted with any of my fun programming projects. So, to celebrate handing it off for evaluation and feedback, I just took this morning to do a massive refactoring of my family gift exchange application.

This was a refactoring to bring it up to date with The Composable Architecture’s ReducerProtocol release, which meant that I ultimately got to delete a bunch of files and simplify a bunch of code. And let me just say, the time it took to do that massive refactor was significantly shorter than the time to perform a similar refactor/code update in the Flutter application.

Gosh, I really enjoy working in Swift!


It’s been quite a while (ten months? a year?) since I deleted my Facebook and Twitter accounts. I do not regret it. Since then, I’ve had far less anxiety force-fed me. I still read news articles, and sometimes feel dismay, but it’s not an unending stream of doom coming at me.

But in the past few days, I’ve received email notifications that a couple people I actually care about have started following my Mastodon account. Which got me feeling a little conflicted.

Continue reading “Social?”