Add posts
parent
18aed71c18
commit
8ca1ca0588
@ -0,0 +1,56 @@
|
||||
---
|
||||
title: "Pixelbook Development Mode: A Cautionary Tale"
|
||||
subtitle: It was all going far too well
|
||||
---
|
||||
|
||||
So for about a month I've been using the Pixelbook as my portable development
|
||||
and note-taking laptop, and it's been generally going well. Like I mentioned in
|
||||
my [first impressions](/pixelbook-first-impressions) post, the
|
||||
pen support is great, Android apps run surprisingly well, and while the Linux
|
||||
container has some quirks it's pretty useful overall.
|
||||
|
||||
My biggest complaint so far, is that enabling ChromeOS developer mode puts it
|
||||
it in a state where it's far too easy to accidentally wipe your system. **(Yes,
|
||||
I say this from experience - it just happened to me.)**
|
||||
|
||||
Putting the Pixelbook in developer mode requires disabling its boot-time OS
|
||||
verification, and every time the device starts it splashes up a warning screen
|
||||
to inform you of this fact. The warning screen helpfully recommends you press
|
||||
the spacebar to re-enable OS verification, but neglects to mention that doing
|
||||
so will factory reset the device.
|
||||
|
||||
> *Developer Mode Boot Screen*
|
||||
>
|
||||
> ![Image of Pixelbook stating "OS verification is off"](/images/chromebook-developer-mode-warning.png)
|
||||
>
|
||||
> Source [Android Central](https://www.androidcentral.com/how-enable-developer-mode-chrome-os)
|
||||
|
||||
If developer mode was more stable, this wouldn't really be an issue - the
|
||||
problem comes from when the device reboots unexpectedly.
|
||||
|
||||
This morning I was using my Pixelbook in tablet mode with the keyboard folded
|
||||
behind it. This configuration puts the keys on the exposed bottom face of the
|
||||
device . . . where I was holding it.
|
||||
|
||||
I was moving some windows around when the system froze and restarted, and before
|
||||
I could realize what was happening my Pixelbook started resetting itself. The
|
||||
way I was holding it, the spacebar was depressed (which normally isn't an issue
|
||||
since keyboard input is disabled in tablet mode, but the bootloader isn't smart
|
||||
enough to know that) and within seconds it had cleared the OS verification
|
||||
screen and started the reset.
|
||||
|
||||
Luckily most of my projects are in git and all the Android apps I was using
|
||||
sync to cloud storage automatically, so I didn't end up losing anything. But it
|
||||
definitely made my heart skip a beat when I saw that powerwash screen come up!
|
||||
|
||||
So if you think you'd like to get the latest features, or pehaps you want to
|
||||
sideload some Android apps onto your Pixelbook - whatever it is, think long and
|
||||
hard about the risk of living one crash away from accidentally resetting your
|
||||
device.
|
||||
|
||||
I think Google should potentially make it a bit harder to activate the powerwash
|
||||
function from the bootloader, but developer mode _is_ supposed to be unstable
|
||||
and dangerous. Personally I'll be sticking to the stable branch from now on,
|
||||
so there's not any risk of this happening again. If you decide developer mode
|
||||
is right for you, be sure to back up your work regularly!
|
||||
|
@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "Adventures with my Pixelbook: Linux Scaling Mode"
|
||||
subtitle: Be warned, it's kind of janky
|
||||
unlisted: true
|
||||
---
|
||||
|
||||
This is just a quick update on one of the largest issues I've had with the
|
||||
ChromeOS Linux app support: display scaling.
|
||||
|
||||
ChromeOS has a display scaling mode for Linux applications that don't handle the
|
||||
high-DPI screen very well, and it generally works okay. It's a bit blurry, but
|
||||
better than having a tiny UI in some applications.
|
||||
|
||||
The downside is that to enable this mode for an app, you need to pin that app
|
||||
to your taskbar.
|
||||
|
||||
I'm not particularly fond of having a full taskbar, so I like to keep just the
|
||||
essentials on there - and what about apps I need to launch with command line
|
||||
parameters? Those can't be pinned to the taskbar without losing that ability.
|
||||
|
||||
If you've run into this issue, then don't worry - there is a solution!
|
||||
|
||||
ChromeOS's Linux container is allowed to draw to the screen through a special
|
||||
X11 server that is run _inside_ the container, and then forwards that image
|
||||
to the Wayland server running in ChromeOS. The magical screen scaling? It's
|
||||
just a second X11 server!
|
||||
|
||||
Therein lies the trick to start apps with window scaling,
|
||||
simply set the `DISPLAY` environment variable to `:1`.
|
||||
|
||||
```shell
|
||||
DISPLAY=:1 firefox
|
||||
```
|
||||
|
||||
Enjoy running your Linux apps without needing a magnifying glass!
|
||||
|
@ -0,0 +1,120 @@
|
||||
---
|
||||
title: Sample Debugging Write-up
|
||||
subtitle: ''
|
||||
unlisted: true
|
||||
---
|
||||
|
||||
> This is a sample write-up of how I investigated an issue for work.
|
||||
>
|
||||
> I'm putting this up with permisison from my former job, but it is ***unlisted***
|
||||
and I would appreciate if you do not share it around.
|
||||
>
|
||||
> Additionally, code screenshots originally included when sending this write-up
|
||||
to my co-workers have been removed so as to not leak confidential information.
|
||||
Where applicable the document has been lightly re-worded to still make sense.
|
||||
|
||||
## Initial Issue
|
||||
|
||||
To start off with, let's talk about the actual bug. We observed that after
|
||||
deploying a small change (which added a few static files and a URL redirect), our A/B
|
||||
test between versions of the site started to act weird. Several of the pages
|
||||
that had been implemented in the new design would briefly display the old UI,
|
||||
then flash abruptly to the new version.
|
||||
|
||||
This issue was easily reproducible, and from our analytics it appeared
|
||||
to be happening to **all** visitors assigned to the old UI. The weirdest part
|
||||
though was that none of those affected pages were at all related to the changes
|
||||
we had eployed!
|
||||
|
||||
At first I didn't really know what was going on, so I started poking around
|
||||
in the sources for the various pages that manifested this issue. I didn't
|
||||
expect there to be anything there, particularly since none of them had been
|
||||
changed in the bad deploy, but it was a good place to start.
|
||||
|
||||
It's important to note here that our A/B testing for this application was
|
||||
done at least in part at the HTTP routing level. Multiple different Next.js page
|
||||
paths were being remapped by our reverse proxy to the same external URL, and
|
||||
so from the beginning I knew something was rather weird here, as the old design
|
||||
wasn't even importing any of the components of the new design. Just from that
|
||||
we knew this couldn't be a component-level issue, and this had something to
|
||||
do with Next's page routing.
|
||||
|
||||
## Weird behavior in webpack
|
||||
|
||||
After quickly double checking there was nothing obvious in the pages themselves,
|
||||
I opened up the browser debugger and checked to see
|
||||
which component files were being loaded. I thought perhaps there
|
||||
could be an issue where the static cached version of the page was the old design
|
||||
but then on rendering in the client it would reset to the new one.
|
||||
|
||||
While I was there, I happened to see something interesting: both versions of the page
|
||||
were having their JS bundles loaded, and both still had sourcemaps cached in the browser developer tools. This seemed
|
||||
weird to me. If the browser were (for some reason) choosing to reload the tab, it would
|
||||
have unloaded all of the old layout's resources. Seeing both loaded at once
|
||||
indicated that Next was doing a *client side* navigation from one to the other.
|
||||
|
||||
So after noting down that I needed to remind the team to disable sourcemaps in production, I started
|
||||
digging into the debugger and dropping breakpoints.
|
||||
|
||||
## Debugging
|
||||
|
||||
I added a breakpoint to Next's `router.push()` and `router.replace()` functions,
|
||||
just to see if they were being called at all.
|
||||
|
||||
As luck would have it, I was right - the `replace()` function *was* being called
|
||||
immediately after the page's first render.
|
||||
Firefox's debugger even helpfully had a call stack for me, with where it was being called from!
|
||||
|
||||
As I clicked through the call stack I found there was a check somewhere in one
|
||||
of Next's internal components - as part of its `componentDidMount()` function
|
||||
there were a few conditions where it would force-reload the page.
|
||||
|
||||
Because of how it's built, Next's sourcemaps were incomplete in the view I had,
|
||||
but after comparing some of the constants in the file I was able to track it down
|
||||
to the file [next/client/index.js](https://github.com/vercel/next.js/blob/v11.1.0/packages/next/client/index.tsx#L181)
|
||||
in the Next.js source (line 181).
|
||||
|
||||
This section definitely looked like it could be causing the issue - the way Next
|
||||
was figuring out what URL to pass to `router.replace()` was relying on the URL
|
||||
in the browser's location history, which means that it would entirely bypass
|
||||
our reverse proxy A/B routing. Unfortunately I didn't yet know why this was
|
||||
being called, or if it was the only reason the page was being reinitialized.
|
||||
|
||||
I spent a while walking through the conditions in this line one by one, using
|
||||
my debugger to check the value of each variable in the faulty production pages,
|
||||
and work out what exactly was happening. It skips the checks for 404 and error pages,
|
||||
since that's not the kind of page we were on, `isFallback` is false so it moves
|
||||
on to the other conditions combined with an `||` there, `data.nextExport` is
|
||||
undefined (as we don't use static export for our site), but `hydrateProps` and
|
||||
`hydrateProps.__N_SSG` were both set!
|
||||
|
||||
So because `hydrateProps` and `hydrateProps.__N_SSG` both exist, it reloads the
|
||||
page if either of the following conditions are true:
|
||||
|
||||
- The page has a query string (`location.search`)
|
||||
- The environment variable `__NEXT_HAS_REWRITES` is set
|
||||
|
||||
Obviously the pages we first observed the bug on didn't have query strings, but
|
||||
the rewrite condition had been optimized by webpack to just `true` so that seemed promising. With a bit more searching I tracked that
|
||||
environment variable to Next's [webpack config](https://github.com/vercel/next.js/blob/v11.1.0/packages/next/build/webpack-config.ts),
|
||||
which seems to set the variable if Next's config file has a rewrite property configured.
|
||||
|
||||
## Confirming the hunch
|
||||
|
||||
At this point it seemed I had found the issue, but I wanted to confirm it without
|
||||
any doubt. So I reverted my local repo to the last commit we had deployed before
|
||||
seeing the issue, and quickly navigated back to that same line in the generated
|
||||
app bundle. This time the `process.env.__NEXT_HAS_REWRITES` condition had been
|
||||
entirely removed, as webpack saw that environment variable was `false` for the build
|
||||
and could never affect the condition.
|
||||
|
||||
Lastly I spun up my full local environment, reverse proxy and all, just to confirm
|
||||
that in as close to a production-like environment as I could. I removed the rewrite
|
||||
rule from the Next.js application and made an equivalent redirect in our reverse
|
||||
proxy - just to make sure I could preserve the intended application behavior without
|
||||
the bug.
|
||||
|
||||
And sure enough - with the redirect behavior moved out of Next.js and into the reverse
|
||||
proxy, the bug entirely disappeared! So I reverted and restored my changes a few times
|
||||
just to double check, and then alerted the other senior developers I had a solution.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
Loading…
Reference in New Issue